聚合初始化-矢量和数组

Aggregate Initialization - Vectors and Arrays

本文关键字:数组 初始化      更新时间:2023-10-16

我知道以下语句适用于

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不工作?

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 },因为支撑的init列表可能只是新变量的初始化器,而不是内置表达式的操作数。(在声明中,=符号只是初始化的一种表示法。它不是通常的运算符。语法特别允许赋值运算符使用括号列表,但这种用法仅在函数重载时有效,这会导致列表初始化一个新变量:函数参数。)

最后一个问题的答案是,没有办法为"裸"数组编写必要的operator =重载,因为它必须是一个成员函数。解决方法是使用std::copystd::initializer_list对象。

正如其他答案中所解释的,该赋值的机制是向量的std::initializer_list赋值运算符。尽管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.af.bf.c分别被分配值1, 4, 0

此外,当非聚合具有参数列表与列表元素兼容的(non-explicit)构造函数时,也可以使用大括号括起来的初始化器列表对其进行初始化和赋值。例如,

struct Bar
{
  Bar(int a, int b, int c) : a(a), b(b), c(c) {} // non-aggregate 
  int a, b, c;
};
Bar b0 = {1, 2, 3}; // OK
Bar b1 = {1,2};     // Error: number of elements must be 3
b0 = {11, 22, 33}.  // Assignemnt OK