#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; }
它打印出六个预期值.
但如果我改变了矢量< str>对于数组< str,3>,gcc给了我这个错误:“std :: array’的初始化器太多了”.
如果我改变了字段的初始化:
array<str,3> fields { str{1,str{3,str{5,6} };
事情很顺利.
那么为什么我在使用std :: array时需要str {1,而在使用std :: vector时只需要{1,2}?
解决方法@H_404_18@
请参阅
aggregate initialization的cppreference部分.
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,6
} };
代替.
另一方面,如何初始化向量由list initialization覆盖.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 type std::initializer_list
请注意,您将无法初始化矢量(如下所示:
vector<str> fields {
1,6
};
但:
vector<int> fields {
1,6
};
很好.
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,6 } };
代替.
另一方面,如何初始化向量由list initialization覆盖.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<str> fields { 1,6 };
但:
vector<int> fields { 1,6 };
很好.