空大括号是调用默认构造函数还是调用 std::initializer_list 的构造函数?
Posted
技术标签:
【中文标题】空大括号是调用默认构造函数还是调用 std::initializer_list 的构造函数?【英文标题】:Do empty braces call the default constructor or the constructor taking an std::initializer_list? 【发布时间】:2015-09-25 12:28:51 【问题描述】:以下引自Effective Modern C++(第55页):
“假设你使用一组空大括号来构造一个支持默认构造函数并且还支持std::initializer_list构造的对象。你的空大括号是什么意思?等等。规则是你得到默认构造。”
我用 std::array: 试过这个
std::array<int, 10> arr;
并从 g++(版本 4.8.2)得到警告:
警告:缺少成员“std::array
::_M_elems”的初始化程序
这是尝试从空的std::initializer_list
构造std::array
时得到的警告(有关此警告的讨论,请参见Why can I initialize a regular array from , but not a std::array)。
那么,为什么上面的代码行不被解释为调用默认构造函数呢?
【问题讨论】:
std::array
没有采用std::initializer_list
的构造函数,并且您在此处拥有的初始化程序也不是std::initailizer_list
。它被称为支撑初始化列表。我不确定您为什么会收到警告,因为使用空大括号应该对嵌套数组进行值初始化。
@0x499602D2 查看我对链接问题的回答,gcc 具有攻击性,并且更高版本的 gcc 不会产生警告。
另请注意,他们在 DR 中以重要的方式更改了 C++11 标准。实际标准说明了一件事,但编译器应该做一些完全不同的事情。
@o11c 你指的是哪个DR?我不清楚您指的是哪种行为。
【参考方案1】:
这是因为std::array 是一个聚合,因此aggregate initialization 被执行,这在draft C++11 standard 部分8.5.4
[dcl.init.list] 中介绍: p>
类型 T 的对象或引用的列表初始化定义如下:
如果初始化列表没有元素并且 T 是具有默认构造函数的类类型,则对象为 值初始化。
否则,如果 T 是聚合,则执行聚合初始化 (8.5.1)。
double ad[] = 1, 2.0 ; // OK int ai[] = 1, 2.0 ; // error: narrowing struct S2 int m1; double m2, m3; ; S2 s21 = 1, 2, 3.0 ; // OK S2 s22 1.0, 2, 3 ; // error: narrowing S2 s23 ; // OK: default to 0,0,0
我们可以看看它是否不是一个聚合然后列表继续说:
否则,如果 T 是 std::initializer_list 的特化,则 initializer_list 对象为 如下所述构造并用于根据初始化规则初始化对象 来自同一类型的类的对象 (8.5)。 否则,如果 T 是类类型,则考虑构造函数。枚举适用的构造函数 并且通过重载决议(13.3、13.3.1.7)选择最好的一个。如果缩小转换(见 下面) 需要转换任何参数,程序格式错误。
我们可以确认std::array
是来自23.3.2.1
部分的聚合[array.overview]:
数组是一个聚合(8.5.1),可以用 语法
array<T, N> a = initializer-list ;
其中 initializer-list 是一个逗号分隔的列表,最多包含 N 个元素 其类型可转换为 T。
引用的8.5.1
部分是8.5.1
聚合[dcl.init.aggr] 并说:
当一个聚合被初始化列表初始化时,指定 在 8.5.4 中,初始化列表的元素被视为 聚合成员的初始化器,增加下标 或会员订单[...]
然后我们回到8.5.4
部分,这是我们开始的地方。
【讨论】:
能否提供您引用的标准文档的链接(当然,如果它可以免费访问)? @MeirGoldenberg 在答案中添加了链接,您可以看到Where do I find the current C or C++ standard documents? 列出了所有可供公众使用的草稿。以上是关于空大括号是调用默认构造函数还是调用 std::initializer_list 的构造函数?的主要内容,如果未能解决你的问题,请参考以下文章