用户定义类型的容器的列表初始化不符合我的预期。
请参阅以下代码段:
#include <array>
struct A {
char C;
int s;
};
int main(int argc, char * argv[]) {
A x = {'x'}, y = {'y'};
std::array<int, 2> i = {1, 2}; // Ok
std::array<A, 2> a = {x, y}; // Ok
//std::array<A, 2> b = { {'x',1000}, {'y',2000} }; // Error: too many initializers!!!
std::array<A, 2> c = { A{'x',1000}, A{'y',1000} };
std::array<A, 2> d = {{ {'x',1000}, {'y',1000} }}; // Ok!!
std::array<A, 2> e = {'x', 2000, 'y', 5000}; // Ok!!
}
我可以将i
初始化为基本数组。只要它们是变量,我就可以使用a进行相同操作。但是我不能在不指定b
类型的情况下初始化A
,例如c
。std::array
而不显式声明A
类型,我必须添加另一对花括号。需要大括号背后的逻辑是什么?为什么不能像b
那样用列表周围的一对大括号来初始化它?c
可以工作,并且只产生两个对象!凭直觉,我希望e
会产生错误,因为有4个初始值,最多2个对象,但是编译器正确地填充了A
的成员!为什么会这样?最佳答案
在考虑任何类型信息之前,将括号嵌套得很深,然后将其与要初始化的对象的结构进行匹配。由于std::array<T,N>
必须在中包含一个真正的T[N]
(而不是一个),因此结构是array
内部只有一个对象,即数组。因此,需要使用两个大括号来启动该数组的初始化程序,如果需要整个嵌套集来初始化一个数组元素,或者如果有多个这样的嵌套集,则此方法无效。
当某些初始化程序子句是表达式甚至A{…}
时,此分解将停止,并且初始化程序将用于一个子对象。但是,如果该表达式不能转换为适当的子对象的类型,并且该类型本身是聚合的,则括号省略会发生,并且尽管缺少括号也将后续的初始化程序用于其子对象。当这适用于T[N]
对象本身时,可以仅用一层括号初始化array
。
因此,简而言之,无论括号是否有效,开放括号都会导致聚合的分解,但是类型不匹配也会导致聚合的分解。
关于c++ - 容器std::array的列表初始化需要双括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64954163/