std::vector 个大小不同的 std::array 个
std::vector of std::array of different sizes
作为练习,我想构造一个包含 std::array<unsigned char, N>
个对象的向量(其中 N
不同)。
我的尝试是构建一个基础 class GenericArray
,MyArray<N>
将从中派生,这样容器实际上就是:std::vector<GenericArray*>
。但是,由于实际的数组变量必须驻留在派生的 class 中,所以我看不到使用 std:vector<GenericArray*>
本身的数据的方法。
这是我的完整尝试,显然会产生:error: ‘class GenericArray’ has no member named ‘data’
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
template<std::size_t N>
using arr_t = std::array<unsigned char, N>;
class GenericArray
{
public:
~GenericArray() = default;
};
template<std::size_t N>
class MyArray : public GenericArray
{
public:
arr_t<N> data;
MyArray(const arr_t<N>& data)
{
this->data = data;
}
};
int main(void)
{
std::vector<GenericArray*> vs;
vs.emplace_back(new MyArray<2>({ 'a', 'b' }));
vs.emplace_back(new MyArray<4>({ 'A', 'B', 'C', 'D' }));
assert(vs.size() == 2);
for (const auto& x : vs[0]->data)
{
std::cout << x << "\n";
}
return 0;
}
I would like to construct a vector containing std::array<unsigned char, N> objects (where N varies).
你不能。像所有标准容器一样,向量是同质的。它们由单一元素类型组成。 std::array<unsigned char, N>
和 std::array<unsigned char, M>
是不同的类型 - 鉴于 N != M,因此它们不能存储在同质容器中。
您可以改用 std::vector<std::vector<unsigned char>>
。
我认为这是不可能的。假设您使用 get
方法制作了一个 class,其中包含 std::array<char,N>
的片段。返回结果的大小应该是多少。编译器必须知道所有用于编译的变量的内存大小,但它不知道 auto p=vct.get(i);
的大小
如果得到 returns 一个指针大小 auto p=*vct.get(i);
未定义。
最接近的是返回 void*
并将其转换为 array<char,N>*
但 N 必须在编译时已知
您似乎混淆了两个概念。我推荐 eerorika 的答案中的版本,但如果你真的想在你的容器中使用基本 class 指针,这是一种方法:
#include <array>
#include <iostream>
#include <vector>
#include <memory>
class GenericArray {
public:
using value_type = unsigned char;
using iterator = value_type*;
template<std::size_t N>
using arr_t = std::array<value_type, N>;
virtual ~GenericArray() = default; // must be virtual to call the derived dtor
virtual iterator begin() = 0; // used for iterating in the derived class
virtual iterator end() = 0;
// add `const` versions too as needed
};
template<std::size_t N>
class MyArray : public GenericArray {
public:
arr_t<N> data;
MyArray(const arr_t<N>& data) : data(data) {}
iterator begin() override { return data.data(); } // overridden
iterator end() override { return data.data() + data.size(); } // -"-
};
int main() { // no need for main(void)
std::vector<std::unique_ptr<GenericArray>> vs;
vs.emplace_back(new MyArray<2>({ 'a', 'b' }));
vs.emplace_back(new MyArray<4>({ 'A', 'B', 'C', 'D' }));
// loop over the elements:
for(auto& ptr : vs) {
for(auto& x : *ptr) std::cout << x << ' ';
std::cout << '\n';
}
}```
作为练习,我想构造一个包含 std::array<unsigned char, N>
个对象的向量(其中 N
不同)。
我的尝试是构建一个基础 class GenericArray
,MyArray<N>
将从中派生,这样容器实际上就是:std::vector<GenericArray*>
。但是,由于实际的数组变量必须驻留在派生的 class 中,所以我看不到使用 std:vector<GenericArray*>
本身的数据的方法。
这是我的完整尝试,显然会产生:error: ‘class GenericArray’ has no member named ‘data’
#include <array>
#include <cassert>
#include <iostream>
#include <vector>
template<std::size_t N>
using arr_t = std::array<unsigned char, N>;
class GenericArray
{
public:
~GenericArray() = default;
};
template<std::size_t N>
class MyArray : public GenericArray
{
public:
arr_t<N> data;
MyArray(const arr_t<N>& data)
{
this->data = data;
}
};
int main(void)
{
std::vector<GenericArray*> vs;
vs.emplace_back(new MyArray<2>({ 'a', 'b' }));
vs.emplace_back(new MyArray<4>({ 'A', 'B', 'C', 'D' }));
assert(vs.size() == 2);
for (const auto& x : vs[0]->data)
{
std::cout << x << "\n";
}
return 0;
}
I would like to construct a vector containing std::array<unsigned char, N> objects (where N varies).
你不能。像所有标准容器一样,向量是同质的。它们由单一元素类型组成。 std::array<unsigned char, N>
和 std::array<unsigned char, M>
是不同的类型 - 鉴于 N != M,因此它们不能存储在同质容器中。
您可以改用 std::vector<std::vector<unsigned char>>
。
我认为这是不可能的。假设您使用 get
方法制作了一个 class,其中包含 std::array<char,N>
的片段。返回结果的大小应该是多少。编译器必须知道所有用于编译的变量的内存大小,但它不知道 auto p=vct.get(i);
的大小
如果得到 returns 一个指针大小 auto p=*vct.get(i);
未定义。
最接近的是返回 void*
并将其转换为 array<char,N>*
但 N 必须在编译时已知
您似乎混淆了两个概念。我推荐 eerorika 的答案中的版本,但如果你真的想在你的容器中使用基本 class 指针,这是一种方法:
#include <array>
#include <iostream>
#include <vector>
#include <memory>
class GenericArray {
public:
using value_type = unsigned char;
using iterator = value_type*;
template<std::size_t N>
using arr_t = std::array<value_type, N>;
virtual ~GenericArray() = default; // must be virtual to call the derived dtor
virtual iterator begin() = 0; // used for iterating in the derived class
virtual iterator end() = 0;
// add `const` versions too as needed
};
template<std::size_t N>
class MyArray : public GenericArray {
public:
arr_t<N> data;
MyArray(const arr_t<N>& data) : data(data) {}
iterator begin() override { return data.data(); } // overridden
iterator end() override { return data.data() + data.size(); } // -"-
};
int main() { // no need for main(void)
std::vector<std::unique_ptr<GenericArray>> vs;
vs.emplace_back(new MyArray<2>({ 'a', 'b' }));
vs.emplace_back(new MyArray<4>({ 'A', 'B', 'C', 'D' }));
// loop over the elements:
for(auto& ptr : vs) {
for(auto& x : *ptr) std::cout << x << ' ';
std::cout << '\n';
}
}```