当前位置:  开发笔记 > 编程语言 > 正文

为什么双空花括号{{}}用一个元素创建一个std :: initializer_list <double>,而不是零?

如何解决《为什么双空花括号{{}}用一个元素创建一个std::initializer_list<double>,而不是零?》经验,为你挑选了2个好方法。

我有以下构造函数:

MyItem(std::initializer_list l) {
    std::cout << "l size " << l.size() << ")" << std::endl;
}

以后用双花括号调用:

MyItem{{}}

结果l.size()给出的是1.

这种行为背后的机制是什么?

似乎嵌套的{}扮演的是唯一元素的默认构造函数,但我不太明白为什么以及类型推导在这里如何工作.



1> chris..:

当您使用大括号(列表初始化)来初始化MyItem对象时,您显示的列表构造函数非常贪婪.

这些将传递一个空列表:

MyItem foo({});
MyItem foo{std::initializer_list{}};

这会传递一个包含单个元素的列表 - 值初始化double(0.0):

MyItem foo{{}};

这是有效的,因为在某些情况下,您可以简单地使用大括号代替已知类型.在这里,它知道从列表构造函数中选择给定列表应该包含的内容double.

为了完整性,这看起来像是传递一个空列表,但foo如果它有一个默认的构造函数,它实际上是值初始化(或者在特殊情况下,它做了几乎相同的事情).如果没有默认构造函数,它将选择列表构造函数,如下所示.

MyItem foo{};


回到问题的例子,更明显的是看到为什么`foo({});`知道从大括号中创建一个`字符串` - 它只有一种类型!以同样的方式,有一条规则说`MyItem foo {{}};`调用将从元素(这里只是内部`{}`)创建一个`initializer_list `,如果可能的话.还有另一个规则是说要从`{}`创建一个`double`,你得到的值为0.0.将这些放在一起你可以看到可以创建一个`initializer_list ` - 一个元素,其中`{}`变成0.0.

2> Vlad from Mo..:

这个表达

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_list l) {
    std::cout << "l size " << l.size() << ")" << std::endl;
}

为显式类型转换选择的.实际上它等同于通话

MyItem( {{}} );

因此构造函数获取具有一个元素的初始化列表

{ {} }

可以使用空括号初始化double类型的标量对象{}.

结果表达式创建了一个类型的临时对象,MyItem该对象由初始化列表初始化,该列表包含一个double类型的元素,该元素通过空括号进行值初始化.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有