我知道以下陈述有效
std::vector<int> a{1,2,4} --->A (Aggregate Initialization)
或以下声明
std::vector<int> a;
a = {1,2,4}; ---->B Variable already initialized. - Then aggregate initialization is called
但是在数组的情况下
int c[3]={1,4}; ---->C (1,4,0)
但是不允许以下内容
int c[3];
c = {1,4}; ---->D
现在我的问题是为什么B工作而D不工作?
答案 0 :(得分:4)
正如其他答案中所解释的,此分配的机制是向量std::initializer_list
assignment operator。尽管std::vector<int>
不是聚合,但是使用大括号括起来的任意值初始化列表列表可以实现以下功能:
std::vector<int> a;
a = {1,2,4}; // OK, vector& operator=(std::initializer_list<T>)
但是不允许以下内容
int c[3];
c = {1,4}; // Error: arrays are not assignable
这是因为数组不可分配。如果它是一种不同类型的聚合,那么这将起作用。例如,
struct Foo { int a, b, c; }; // aggregate
Foo f = {1, 2, 3}; // OK, aggregate initialization
f = { 1, 4 }; // OK
此处,f.a
,f.b
和f.c
分别为1, 4, 0
分配值。
此外,当非({ - 1}})构造函数具有与列表元素兼容的参数列表时,非聚合也可以使用大括号括起的初始化列表进行初始化和赋值。例如,
explicit
答案 1 :(得分:3)
std::vector<int> a{1,2,4};
这是初始化列表初始化,而不是聚合,因为vector
不是聚合 - 它的数据存储在堆上。您需要#include <initializer_list>
才能使用它,尽管该标头通常包含在<vector>
中。
a = {1,2,4};
这也通过std::initializer_list
上的函数重载,语义与函数调用相同:
a.assign( {1,2,4} );
int c[3]={1,4};
此是聚合初始化。但是之后你不能做c = { 3, 5, 6 }
,因为braced-init-lists只能是新变量的初始值设定项,而不是内置表达式的操作数。 (在声明中,=
符号只是初始化的符号。它不是通常的运算符。赋值运算符的语法特别允许使用支撑列表,但这种用法仅对函数重载有效,这会导致用于初始化新变量的列表:函数参数。)
最后一个问题的答案是,无法为“裸”数组编写必要的operator =
重载,因为它必须是成员函数。解决方法是使用std::copy
和std::initializer_list
对象。