在这种情况下可以使用std::array(或boost::array)吗?或者我是不是一直使用std::vector和本



因此,std::array和boost::array(它们几乎相同,我在下文中将含糊地称为"array")旨在为数组提供一个容器对象,该对象不会产生向量开销,如果数组不动态更改大小,则这些开销是不必要的。然而,它们都是通过将数组大小不是构造函数参数而是模板参数来设计的。结果:矢量允许在对象创建后动态调整大小;数组要求在编译时知道大小。

据我所见,如果您有一个数组,您在创建对象时就知道它的大小,但在编译时却不知道,那么您唯一的选择是1)使用向量会带来不必要的额外开销,2)使用(非容器类型)本机数组(如int foo[42];),或3)从头开始编写自己的数组包装类。这是正确的吗?这是一种介于两者之间的情况,你可能想使用数组而不是向量,但不能?或者我能做一些魔法,让阵列对我有用吗?

以下是激发这个问题的一个小细节(好吧,很多),以防它能帮助你理解:

我有一个模块,比如调用者,它将在运行时重复生成二进制数据(unsigned char[]或array),然后将其传递给另一个模块——比如被调用者。被调用方模块不会修改数组(如果需要,它会复制并修改),因此一旦调用方模块最初创建了数组,它就不会更改大小(实际上也不会更改内容)。然而,会出现两个问题:1)调用方可能不会在每次生成数组时生成相同大小的数组——它在创建数组时会在rutime知道数组大小,但在编译时不会知道。2) 调用者将数组传递给被调用者的方法需要能够接受调用者传递给它的任何大小的数组

我想把它作为一个模板函数,例如

template<size_t N> void foo(const array<unsigned char, N>& my_array);

然而,我使用接口类将接口与被调用者模块中的实现分离。因此,函数必须是一个虚拟方法,它与被模板化是互斥的。此外,即使这不是问题,它仍然会遇到与上面#1相同的问题——如果在编译时数组大小未知,那么它也无法在编译时解决模板化函数。

我的实际功能:

virtual void foo(const array<unsigned char, N>& my_array); // but what is N???

总之,我唯一真正的选择是使用向量或原生数组,例如,这一点正确吗

virtual void foo(const vector<unsigned char> my_array); // unnecessary overhead
virtual void foo(const unsigned char[] my_array, size_t my_array_len); // yuk

或者我忽略了一些技巧,让我使用std::array或boost::array?

在C++11中有std::dynarray之前,您可以使用std::unique_ptr:

std::unique_ptr<Foo[]> arr(new Foo[100]);

您可以将其用作arr[0]arr[1]等,并且它将在销毁时调用正确的delete[]。开销是最小的(只有指针)。

我认为数组类型的唯一指针和std::dynarray之间的唯一区别是后者具有迭代器和size其他"容器"属性,并且它将在"容器"部分而不是"通用实用程序"中。[更新:编译器可以选择本机支持dynarray,并对其进行优化以使用堆栈存储。]

如果在编译时不知道长度,就不能使用任何形式的std::数组。

如果在编译时不知道数组的大小,请认真考虑使用std::vector。使用可变长度数组(如int foo[n])不是标准C++,如果给定的长度足够大,则会导致堆栈溢出。此外,您不能用(可测量的)比std::vector更少的开销来编写任何类似数组的包装器。

我只想用

virtual void foo(const unsigned char* my_array, size_t my_array_len);

并称之为

obj.foo(&vec[0], vec.size());

没有附加开销,它可以随心所欲。除了普通数组(int foo[42])之外,这也可以用零开销的向量和std::数组来调用。

其他注意事项:

  • 数组是在堆栈上分配的。这比在堆上分配快得多
  • 数组总是在创建时初始化其所有元素

因此:

    class Foo;
    std::array<Foo, 100> aFoo;

构造100个Foo对象(调用Foo::Foo() 100次),而

    std::vector<Foo> vFoo;
    vFoo.reserve(100);

为100个Foo对象(在堆上)保留空间,但不构造任何对象。

最新更新