为什么双空花括号 { { } } 创建一个 std::initializer_list<double> 有一个元素,而不是零?
Why does double empty curly braces { { } } create a std::initializer_list<double> with one element, not zero?
我有以下构造函数:
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
后面用双花括号调用:
MyItem{{}}
l.size() 给出的结果是 1。
这种行为背后的机制是什么?
似乎嵌套的 {} 就像唯一元素的默认构造函数一样,但我不太明白为什么类型推导在这里起作用以及如何起作用。
当您使用大括号(list-initialization)初始化MyItem
对象时,您显示的列表构造函数非常贪心。
这些将传递一个空列表:
MyItem foo({});
MyItem foo{std::initializer_list<double>{}};
这传递了一个包含单个元素的列表 - a value-initialized double
(0.0):
MyItem foo{{}};
之所以可行,是因为在某些情况下您可以简单地使用大括号代替已知类型。在这里,它通过首选列表构造函数知道给定列表应包含 double
.
为了完整起见,这看起来像是传递了一个空列表,但实际上 value-initializes foo
如果它有一个默认构造函数(或者在特殊情况下,做一些几乎相同的事情)。如果没有默认构造函数,它将选择列表构造函数,as shown here.
MyItem foo{};
这个表达式
MyItem{{}}
表示显式类型转换(函数符号)。
根据 C++ 标准(5.2.3 显式类型转换(函数符号))
- Similarly, a simple-type-specifier or typename-specifier followed by a
braced-init-list creates a temporary object of the specified type
direct-list-initialized (8.5.4) with the specified braced-init-list,
and its value is that temporary object as a prvalue.
Class MyItem 有转换 initializer-list 构造函数
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
选择显式类型转换。实际上相当于调用
MyItem( {{}} );
所以构造函数得到一个只有一个元素的初始化列表
{ {} }
double 类型的标量对象可以用空大括号初始化 {}
。
结果,该表达式创建了一个 MyItem
类型的临时对象,该对象由一个初始化列表初始化,该列表包含一个双精度类型的元素,即 value-initialized 通过空大括号。
我有以下构造函数:
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
后面用双花括号调用:
MyItem{{}}
l.size() 给出的结果是 1。
这种行为背后的机制是什么?
似乎嵌套的 {} 就像唯一元素的默认构造函数一样,但我不太明白为什么类型推导在这里起作用以及如何起作用。
当您使用大括号(list-initialization)初始化MyItem
对象时,您显示的列表构造函数非常贪心。
这些将传递一个空列表:
MyItem foo({});
MyItem foo{std::initializer_list<double>{}};
这传递了一个包含单个元素的列表 - a value-initialized double
(0.0):
MyItem foo{{}};
之所以可行,是因为在某些情况下您可以简单地使用大括号代替已知类型。在这里,它通过首选列表构造函数知道给定列表应包含 double
.
为了完整起见,这看起来像是传递了一个空列表,但实际上 value-initializes foo
如果它有一个默认构造函数(或者在特殊情况下,做一些几乎相同的事情)。如果没有默认构造函数,它将选择列表构造函数,as shown here.
MyItem foo{};
这个表达式
MyItem{{}}
表示显式类型转换(函数符号)。
根据 C++ 标准(5.2.3 显式类型转换(函数符号))
- Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is that temporary object as a prvalue.
Class MyItem 有转换 initializer-list 构造函数
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
选择显式类型转换。实际上相当于调用
MyItem( {{}} );
所以构造函数得到一个只有一个元素的初始化列表
{ {} }
double 类型的标量对象可以用空大括号初始化 {}
。
结果,该表达式创建了一个 MyItem
类型的临时对象,该对象由一个初始化列表初始化,该列表包含一个双精度类型的元素,即 value-initialized 通过空大括号。