这段 C++11 代码对我来说工作正常:
#include <iostream>
#include <vector>
#include <array>
using namespace std;
struct str {
int first, last;
};
vector<str> fields {
{1,2}, {3,4}, {5,6}
};
int main()
{
for (str s : fields)
cout << s.first << " " << s.last << endl;
}
它打印六个期望值。
但是如果我改变vector<str>
至 array<str,3>
, gcc 给我这个错误:“'std::array' 的初始值设定项太多”。
如果我更改 fields
的初始化因此:
array<str,3> fields {
str{1,2}, str{3,4}, str{5,6}
};
一切正常。
那么为什么我需要 str{1,2}
使用 std::array
时, 但只有 {1,2}
使用 std::vector
时?
最佳答案
参见 cppreference 的关于 aggregate initialization 的部分.
The effects of aggregate initialization are:
Each array element or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
If the initializer clause is a nested braced-init-list, the corresponding class member is itself an aggregate: aggregate initialization is recursive.
这意味着如果您的结构中有一个聚合,例如:
struct str {
struct asdf
{
int first, last;
} asdf;
};
asdf
将由第一个嵌套的 brace-init-list 初始化,即 { { 1, 2 } }
。你通常需要两对大括号的原因是因为嵌套的 brace-init-list 初始化 std::array
中的底层聚合(例如,T a[N]
).
但是,您仍然可以像这样初始化数组:
array<str,3> fields {
1, 2, 3, 4, 5, 6
};
或:
array<str,3> fields { {
1, 2, 3, 4, 5, 6
} };
相反。
另一方面,list initialization 涵盖了如何初始化 vector 。 . std::vector
有一个接受 std::initializer_list
的构造函数.
The effects of list initialization of an object of type T are:
Otherwise, the constructors of T are considered, in two phases:
- All constructors that take
std::initializer_list
as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of typestd::initializer_list
请注意,您将无法初始化 vector (像这样:
vector<str> fields {
1,2, 3,4, 5,6
};
但是:
vector<int> fields {
1,2, 3,4, 5,6
};
非常好。
关于c++ - std::vector 和 std::array 初始化列表之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26179353/