C++ 嵌套std::数组中的数据是否保证是连续的?

C++ 嵌套std::数组中的数据是否保证是连续的?,c++,multidimensional-array,c++11,C++,Multidimensional Array,C++11,std::array中的数据是否保证是连续的?例如: #include <array> #include <cassert> int main() { enum {M=4, N=7}; typedef std::array<char,N> Row; typedef std::array<Row, M> Matrix; Matrix a; a[1][0] = 42; const char* data

std::array
中的数据是否保证是连续的?例如:

#include <array>
#include <cassert>

int main()
{
    enum {M=4, N=7};
    typedef std::array<char,N> Row;
    typedef std::array<Row, M> Matrix;
    Matrix a;
    a[1][0] = 42;
    const char* data = a[0].data();

    /* 8th element of 1D data array should be the same as
       1st element of second row. */
    assert(data[7] == 42);
}
#包括
#包括
int main()
{
枚举{M=4,N=7};
typedef std::数组行;
typedef std::数组矩阵;
基质a;
a[1][0]=42;
const char*data=a[0].data();
/*1D数据数组的第8个元素应与
第二行的第一个元素*/
断言(数据[7]==42);
}
这个断言一定会成功吗?或者,换一种说法,我能指望
行的末尾没有填充吗


编辑:为了清楚起见,在本例中,我希望整个矩阵的数据是连续的。

它们很可能是连续的。如果不是,编译器会主动与您进行斗争。不能保证它不会插入填充物,但几乎没有理由这样做

这个断言一定会成功吗


数据[7]
是一种越界访问(未定义的行为)。内部数组对象只有七个元素,因此索引7无效。

否,在这种情况下不保证连续性

std::array
保证是一个聚合,并且指定用于存储的底层数组必须是该类型的第一个数据成员


但是,不要求
sizeof(array)==sizeof(T)*N
,也不要求对象末尾没有未命名的填充字节,或者
std::array
除了底层数组存储之外没有数据成员。(不过,包含额外数据成员的实现充其量是不寻常的。)

即使存储是连续的,我相信您也会违反别名规则。看到这个问题了吗?我在很多个月前问过这个问题(当然是关于C):.by的可能重复recursion@LightnessRacesinOrbit字体不,我不认为它是复制品。虽然单个
std::array
中的数据是连续的,但这并不意味着嵌套
std::array
s中的整个数据集是连续的。或者至少对于像我这样的非语言律师来说,这并不明显。@Emile:是的,是的。如果
std::array
中的每个元素都是连续的,那么这意味着
std::array
中的每个
std::array
都直接与下一个相邻。而且,通过递归,这些“子”
std::array
s中的每一个也是连续的。一个容器不会因为它自己的
值类型
而突然神奇地失去连续性(如果这确实是容器的保证)。[编辑:然而,这与最内部的
T
s彼此相邻并不相同。看来这毕竟是你的意思,所以,很好:P]@LightnessRacesinOrbit:就像James在回答中所说的那样,没有要求在
数组的末尾没有填充或额外的数据成员,虽然我承认,体面的实现并不能做到这一点。嗯,你的答案似乎有点矛盾(或者我只是太过密集)。如果数据是连续的,
data[7]
会不会指向第二行的第一个元素?@Emile认为“1D数据数组的第八个元素应该与第二行的第一个元素相同”的缺陷在于忽略了该代码中没有数组有第八个元素。因此,无法保证
数据[7]
会起到什么作用。实际上,是的,我怀疑它会指向第二行的第一个元素,但与UB一样,您不能安全地依赖它。好的,那么我认为“它们很可能是连续的”意味着每个内部数组中的数据是连续的。这就是你的意思吗?每个内部数组也彼此相邻。但在索引时,不能从一个交叉到另一个。这不是一个std::array
的东西。
intx[4][7]也是如此;int*xp=x;xp[7]。“它们很可能是连续的”,我的意思是没有一个健全的编译器会插入任何填充。@Emile:我想澄清一下,回到你最初的问题:我不介意依赖没有填充(我不想支持一个做这种疯狂事情的编译器!),因为它实际上可以被测试:
static\u assert(sizeof)(Matrix)==sizeof(char)*M*N,“嵌套的std::数组应该没有填充”);
。我更厌倦依赖索引作为一个大数组,因为这无法测试(它现在可以工作,通常也可以,但当优化器决定利用它进行优化时,可能会失败)。