简体   繁体   English

不同大小的 std::array 的 std::vector

[英]std::vector of std::array of different sizes

As an exercise, I would like to construct a vector containing std::array<unsigned char, N> objects (where N varies).作为练习,我想构造一个包含std::array<unsigned char, N>对象(其中N不同)的向量。

My attempt was to construct a base class GenericArray from which a MyArray<N> will derive, such that the container will actually be: std::vector<GenericArray*> .我的尝试是构建一个基类GenericArray ,从中派生MyArray<N> ,这样容器实际上是: std::vector<GenericArray*> However, since the actual array variable must reside in the derived class, I do not see a way to make use of this data from the std:vector<GenericArray*> itself.但是,由于实际的数组变量必须驻留在派生类中,因此我看不到可以利用std:vector<GenericArray*>本身的数据的方法。

Here is my full attempt, which obviously produces: error: 'class GenericArray' has no member named 'data'这是我的完整尝试,这显然会产生: 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> 对象(其中 N 不同)的向量。

You cannot.你不能。 Vectors, like all standard containers are homogeneous.向量,就像所有标准容器一样,是同质的。 They consist of a single element type.它们由单一元素类型组成。 std::array<unsigned char, N> and std::array<unsigned char, M> are different types - given that N != M, and thus they cannot be stored in a homogeneous container. std::array<unsigned char, N>std::array<unsigned char, M>是不同的类型——假设 N != M,因此它们不能存储在同构容器中。

You can use std::vector<std::vector<unsigned char>> instead.您可以改用std::vector<std::vector<unsigned char>>

You seem to be mixing two concepts.你似乎混合了两个概念。 I recommend the version in eerorika's answer but if you really want base class pointers in your container, here's one way:我推荐 eerorika 的答案中的版本,但如果你真的想要在你的容器中使用基类指针,这是一种方法:

#include <array>
#include <iostream>
#include <vector>
#include <memory>

template<std::size_t N>
using arr_t = std::array<unsigned char, N>;

class GenericArray {
public:
    virtual ~GenericArray() = default;  // must be virtual to call the derived dtor
    virtual unsigned char* begin() = 0; // used for iterating in the derived class
    virtual unsigned char* 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) {}
    unsigned char* begin() override { return data.begin(); } // overridden
    unsigned char* end() override { return data.end(); }     // -"-

};

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';
    }
}

I don't think it is possible.我不认为这是可能的。 Let's say you make a class which contains a secvence of std::array<char,N> s with a get method.假设您使用get方法创建了一个包含std::array<char,N> secvence 的类。 what should be the size of the returned result.返回结果的大小应该是多少。 The compiler must know the memory-size of all, variables for compiling, but it doesn't know the size of auto p=vct.get(i);编译器必须知道所有用于编译的变量的内存大小,但它不知道auto p=vct.get(i);的大小auto p=vct.get(i); If get returns a pointer than size size of auto p=*vct.get(i);如果 get 返回的指针比auto p=*vct.get(i);大小大小auto p=*vct.get(i); is undefined.未定义。

The closest you can get is returning void* and casting it to array<char,N>* but N must be known compile-time最接近的是返回void*并将其转换为array<char,N>*但 N 必须在编译时已知

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM