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