二维std::array的初始化列表

3
为什么int类型的二维数组初始化是连续的,而二维向量则是按数字集初始化的?
int main()
{
  array<array<int, 2>, 2> td{ 2, 6, 4, 8 }; //array of arrays
  for (int i = 0; i < 2; ++i)
    for(int j = 0; j < 2; ++j)
      cout << td[i][j] << ' ';

  cout << endl;

  vector<vector<int>> vtd{ { 5, 1 }, { 0, 2 } };  //vector of vectors
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      cout << vtd[i][j] << ' ';

  return 0;
}

这里是结果:
2 6 4 8
5 1 0 2

大多数编译器应该会为std::array的初始化提供警告,因为它确实缺少花括号。 - Some programmer dude
如果我在VS2013 MSVC编译器中使用{{0,1},{2,3}}进行初始化,会出现编译错误。然后我使用了{0,1,2,3},它可以正常工作。 - Kenneth Bastian
4个回答

3

std::array 是一个聚合类型。当使用花括号初始化列表对聚合类型进行初始化时,每个子聚合类型按顺序从列表中获取所需的元素数量,并使用列表的余下部分来初始化下一个元素,以此类推。特别地,这意味着 td 中的第一个数组获取了前两个初始化值(因为它有两个元素),而第二个数组获得了剩余的两个值。

std::vector 不是聚合类型,它有一个明确定义的构造函数,该构造函数将 std::initializer_list 作为参数,用于确定列表初始化的语义。


谢谢。此外,根据《C++程序设计语言》(第四版),它是一个由类型为TN个连续元素组成的固定大小数组。 - Kenneth Bastian

1

std::vector是一个封装了一组内部状态的对象:{ T* data, size_t count, size_t capacity }。实际的向量内容存储在内存中的其他位置。

相比之下,std::array是围绕C风格数组的封装层。它没有内部状态,而是直接位于C数组上方。

std::vector<int> v;
v.reserve(4);
std::array<int, 4> a;

在此之后,您在堆栈上的内容如下:
[ int* v.data ]
[ size_t v.count = 0 ]
[ size_t v.size = 4 ]
[ int[4] ]

作为结果,你的 2 层 std::vector 实际上是一个对象的向量。
[ std::vector<int>* v.data --> points to second tier object in heap memory ]
[ size_t v.count ]
[ size_t v.size ]

std::array实际上只是int a[2][2]的别名,它的初始化方式与您预期的完全相同。


1
一个数组的数组和一个向量的向量之间的区别就像普通数组的数组与指针的指针之间的区别一样。 std::array类非常接近于普通数组(必须是连续的),而std::vector则更接近于指针。

0

std::array 是一个非常薄的静态数组包装器。它在编译时分配,具有已知大小,并且每个元素都保证是连续的,因此当您拥有一个数组的数组时,它们将全部是连续的。

示例:

std::array<T, 4> a;
|   a[0]   |   a[1]   |   a[2]   |   a[3]   |

std::array<std::array<T, 2>, 2> b;
|   a[0][0]   |   a[0][1]   |   a[1][0]   |   a[1][1]   |

由于第一个数组 (a [0] ) 和第二个数组一样,被保证是连续的,并且父包装器数组也被保证是连续的,整个结构将是连续的。

对于向量,它在运行时确定。如果是向量的动态数组,则保证是连续的,如果是向量的向量,则父向量中的每个元素都有一个指向单独的连续内存块的指针(每个“子”向量都有大小、容量和指向连续内存块的指针)。

类比如下:

T t[...][...] ====> std::array<std::array<T, ...>, ...>
T** t         ====> std::vector<std::vector<T>>

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