C++ 为什么初始值设定项列表只能用于声明?

C++ 为什么初始值设定项列表只能用于声明?,c++,arrays,initializer-list,C++,Arrays,Initializer List,数组可以用所谓的初始化列表进行初始化 例如: 当数组有一组初始值时,这非常有用。 但是,一旦声明了数组,这种方法就无法为数组分配新值 my_array = {10, 20, 30}; error: assigning to an array from an initializer list 然而,有时我们需要多次将数组初始化为一些初始值(例如:在循环中),因此我认为能够使用初始值设定项列表为已经声明的变量赋值是非常有用的 my_array = {10, 20, 30}; error: as

数组可以用所谓的初始化列表进行初始化

例如:

当数组有一组初始值时,这非常有用。 但是,一旦声明了数组,这种方法就无法为数组分配新值

my_array = {10, 20, 30};

error: assigning to an array from an initializer list
然而,有时我们需要多次将数组初始化为一些初始值(例如:在循环中),因此我认为能够使用初始值设定项列表为已经声明的变量赋值是非常有用的

my_array = {10, 20, 30};

error: assigning to an array from an initializer list
我的问题是:是否有理由在声明时而不是在声明数组时拥有这样的特性?
为什么它在一个案例中工作,而不是在另一个案例中?

< P>数组是C++中的二等公民。 它们是物体, 但它们受到严格限制: 它们不能被复制, 它们在不同的上下文中被分解成指针,等等。 考虑使用<代码> STD::数组< /代码>, 它是内置阵列顶部的(固定大小)包装, 但他是一等公民,支持各种便利功能:

std::array<int, 3> my_array = {10, 20, 30};
my_array = {40, 50, 60};
使用它:

int arr[3] = {10, 20, 30};
assign(arr, 40, 50, 60);
现在
arr
40、50、60
组成

数组可以用所谓的初始化列表进行初始化

嗯,没有

类可以用初始化列表初始化。它们必须有一个构造函数,该构造函数采用
std::initializer\u list

示例

vector( std::initializer_list<T> init, const Allocator& alloc = Allocator());
向量(std::initializer_list init,const分配器&alloc=Allocator()); 数组不是类,所以它们不能有构造函数。但它们可以通过以下方式初始化:

聚合是以下类型之一:

  • 数组类型
正如L.F.所说:它们不能复制:

分配

数组类型的对象不能作为一个整体进行修改:即使它们 是左值(例如,可以获取数组的地址),它们不能 出现在赋值运算符的左侧

资料来源:

这就是为什么
{}
syntax用于初始化而不用于赋值,因为它的含义不同

是否有理由在声明时而不是在声明数组时使用此功能?为什么它在一种情况下有效,而在另一种情况下无效

x={a,b,…}
语法涉及一种称为复制列表初始化的特定类型的初始值设定项列表。中提到了使用复制列表初始化的可能方法:

  • T object={arg1,arg2,…}(6)
  • 函数({arg1,arg2,…})
    (7)
  • 返回{arg1,arg2,…}(8)
  • 对象[{arg1,arg2,…}]
    (9)
  • object={arg1,arg2,…}
    (10)
  • U({arg1,arg2,…})
    (11)
  • Class{T member={arg1,arg2,…};}(12)
您尝试的数组语法
T myArr[]={a,b,c..}
有效,并被计算为(6)在等号后使用带括号的init列表初始化命名变量

不适用于您的语法(
myArr={a,b,…}
)计算为(10),在赋值表达式中称为列表初始化。赋值表达式的问题是左侧必须是所谓的左值,尽管数组是左值,但它们不能出现在赋值的左侧


也就是说,通过将初始值设定项列表复制到数组中来解决赋值问题并不难:

#包括
#包括
int main(){
int arr[]={1,2,3};
自动itr=arr;
自动赋值={5,2,1};
std::copy(assign.begin()、assign.end()、itr);
}

这可能使用
std::vector
而不是原始数组来工作。您可能需要检查以下答案:它确实适用于vector。但数组不是动态数组:)它不能改变它的大小(我们不知道初始值设定项列表中有多少个元素),除了@πάνταῥεῖ 注释,对于可以使用的固定大小数组。数组到指针的衰减适用于
=
的操作数,因此实际上这会尝试将大括号列表分配给指针,这是不允许的。现在无法更改衰减,太多的代码将被破坏。您可以从
sizeof…(Args)
获取
N
,它必须match@Caleth是的,但是当
sizeof…(Args)!=N
。为什么要投反对票?如果我遗漏了什么,请告诉我。我不是向下投票人,但我想指出的是,“数组可以用所谓的[initializer]列表进行初始化”与“数组可以用聚合初始化进行初始化”并不矛盾
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator());