std::array 与 C 风格数组的区别

4

我听说在C++中,应该始终使用std::array而不是c风格的数组。

在查看了很多问题后,我发现很多人都认为std::array更好。

因此,我经常使用std::array,有时候当我使用其他库时,需要使用接受c风格数组的方法。

例如,我正在使用这个函数:

void Draw(float* arg);

可以将std::array<float,4>作为参数传递吗?

如果我将&vec4[0]作为参数传递,是否会有未定义的行为?

在这种情况下,多维数组也是一样的吗?

使用以下声明的数组:

std::array<std::array<float,4>,4>;

如果我将 &mtx4[0][0] 作为参数传入,是否也会出现未定义的行为?

编辑:感谢指出多维数组代码中的错误。我已进行了修改。


4
std::array 只是作为其成员的一个数组。该数组的行为与其他数组相同。但是,考虑使用 .data()。而且您的“多维数组”示例甚至不能在普通数组中使用。不要期望从2D std::array 中得到任何神奇的东西。 - chris
2
“能否将std::array<float,4>作为参数传递?” 可以! Draw( my_cpp_array.data() ); 你问了很多问题,我都快筋疲力尽了。 :) - Drew Dormann
1
关于 std::array 的一个好处是,如果您使用 at() 方法来访问数据,它将进行边界检查,从而使您免受著名的“off-by-one”错误的困扰,这种错误在原始数组上并不总是容易检测到。http://en.wikipedia.org/wiki/Off-by-one_error - glampert
2
关于您上一个问题:绝对不行。您知道float[4][4]float**是不兼容的,对吗? - n. m.
现在,您可以将&mtx [0] [0]传递给请求float *的函数。但是,您不能将&mtx [0]mtx传递给期望float(* arg)[4]的函数,在C中声明为float mtx [4] [4];时可以这样做。 - WhozCraig
显示剩余3条评论
1个回答

0
能够将 std::array 作为参数传递吗?
可以。正确的语法是:
Draw(my_array.data());

如果我将&vec4[0]作为参数传递,会有任何未定义的行为吗?
不会。从语法上讲,它不太能清楚地表达您的意图,但从语义上讲,它是相同的。
在这种意义下,对于多维数组也是一样的吗?
是的,如果您指的是经典的C多维数组,它们实际上只是与索引信息相关联的平坦数组。如果您指的是C数组的数组,则不是。
float array2d[5][5]; // ok
float *array2d[5]; // not ok
std::array<std::array<float,5>,5> array2d; // not ok

第一个具有连续的存储空间。另外两个是指向数组的指针数组,需要以不同的方式处理。这里没有足够的信息来推荐如何处理。

我在这里找到了一个参考链接,介绍了一种新的多维数组语法。它应该提供连续的存储。

std::array<float,5,5>; // should be ok

我真的不知道这个语法的状态如何。也许其他人可以帮忙。


在进一步调查这个声明之后:

std::array<std::array<float,5>,5> array2d;

这里的array2d存储是全部内联的,没有涉及到指针。在我所调查的所有情况中,存储似乎都是连续的,因此内存布局与...相同。
float array2d[5][5];

这不是标准的要求。符合规范的实现可以插入额外的信息或填充,使得对于某些T,sizeof(array<T>)sizeof(T[])更大。如果这样做,那么这两者的存储布局将不相同。


4
我不确定你在最后一点上的意思,但是std::arraystd::array具有连续的存储空间。 它就像一个经典的C多维数组。 - juanchopanza
3
@david.pfx:您确实需要更正您的最后一点。 std::arraystd :: array 数组中没有涉及“指向数组的指针数组”。 - Blastfurnace
2
@david.pfx: §23.3.2.1 [array.overview],“数组的元素是连续存储的,这意味着如果a是一个数组<T,N>,那么它遵循恒等式&a[n] == &a[0] + n,其中0 <= n < N”。这要求std::arraystd::array是一个连续数组的连续数组。 - Blastfurnace
1
@david.pfx 为什么不提供存储连续的证据?你找不到,因为根本没有。 - juanchopanza
2
我看不出如何在满足std::array的所有要求的同时实现它。另一方面,你实际上是在做一个毫无根据的断言。 - juanchopanza
显示剩余17条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接