我有以下构造函数:
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
以后用双花括号调用:
MyItem{{}}
l.size()给出的结果是1。
这种行为背后的机制是什么?
似乎嵌套{}扮演的是唯一元素的默认构造函数,但我不太明白为什么以及类型推导如何在这里工作。
答案 0 :(得分:10)
当您使用大括号(列表初始化)初始化MyItem
对象时,您显示的列表构造函数非常贪婪。
这些会传递一个空列表:
MyItem foo({});
MyItem foo{std::initializer_list<double>{}};
这会传递一个包含单个元素的列表 - 值初始化double
(0.0):
MyItem foo{{}};
这是有效的,因为在某些情况下,您可以简单地使用大括号代替已知类型。在这里,它更喜欢列表构造函数,给定列表应包含double
。
为了完整性,这看起来像是传递了一个空列表,但如果它有一个默认构造函数,它实际上会初始化foo
(或者在特殊情况下,它会做几乎相同的事情)。如果没有默认构造函数,它将选择列表构造函数as shown here。
MyItem foo{};
答案 1 :(得分:5)
此表达式
MyItem{{}}
表示显式类型转换(功能表示法)。
根据C ++标准(5.2.3显式类型转换(功能表示法))
- 类似地,一个simple-type-specifier或typename-specifier后跟一个 braced-init-list创建指定类型的临时对象 direct-list-initialized(8.5.4)与指定的braced-init-list, 它的值是临时对象作为prvalue。
醇>
类MyItem具有转换初始化列表构造函数
MyItem(std::initializer_list<double> l) {
std::cout << "l size " << l.size() << ")" << std::endl;
}
为显式类型转换选择的。实际上它等同于调用
MyItem( {{}} );
因此构造函数获取带有一个元素的初始化列表
{ {} }
可以使用空括号{}
初始化double类型的标量对象。
结果表达式创建了一个MyItem
类型的临时对象,该对象由初始化列表初始化,该列表包含一个double类型的元素,该元素通过空括号进行值初始化。