为什么在聚合类型推导中不支持花括号初始化列表,但支持花括号省略?
另一个我认为很奇怪的问题是,如果Xi是用于初始化子聚合的大括号初始化列表,如果bullet [1.5]成立,则Xi将用于初始化子聚合的元素。这是什么意思?
更新
在进一步研究p2082r1之后,从其上下文来看,“聚合元素”一词似乎是指聚合类型的元素而不是聚合的元素。如果满足bullet [1.5]、[1.6]、[1.7],则ei将成为聚合元素。然而,如果这些bullet都不符合要求,那么ei会是什么呢?这里似乎没有明确定义。
#include <iostream>
template<typename T>
struct Test{
T t[2];
};
int main(){
Test t{{1,2}}; // #1
// Test t1{1,2} // #2
}
#1
被GCCrejected,而#2
会被GCC接受。
此外,如果定义了C并且它的定义满足聚合类的条件([dcl.init.aggr]),假设任何相关基类都没有虚函数和虚基类,并且初始化程序是非空的大括号初始化列表或带括号的表达式列表,并且C没有模板参数推导,则集合包含一个额外的函数模板,称为聚合推导候选项,其定义如下。设X1,...,XN是大括号初始化列表或表达式列表的元素。对于每个Xi,让ei是与C或其(可能递归)子聚合中的一个将被Xi初始化的相应聚合元素,如果
- [1.5] 未考虑任何具有依赖性非数组类型或带有值依赖性绑定的数组类型的聚合元素的大括号省略,以及
- [1.6] 每个不在末尾的聚合扩展的聚合元素被假定不对初始化列表的任何元素对应,以及
- [1.7] 作为扩展包的末尾聚合元素被假定对应于初始化列表的所有剩余元素(如果有)。
如果没有任何Xi的这种聚合元素ei,则不会将聚合推导候选项添加到集合中。该聚合推导候选项是从假想构造函数C(T1,...,Tn)中派生出来的,如上所述
- 如果ei是数组类型且xi是大括号初始化列表或字符串文字,则Ti是对ei的声明类型的右值引用
在我的例子中,x1是一个大括号初始化列表({1,2}
),而e1的类型是数组类型T[2],因此构造函数应该是形式为C(T(&&)[2])
,并且可以从temp.deduct.call#1中根据{1,2}
推导出T(&&)[2]
的模板参数。
另一个我认为很奇怪的问题是,如果Xi是用于初始化子聚合的大括号初始化列表,如果bullet [1.5]成立,则Xi将用于初始化子聚合的元素。这是什么意思?
更新
在进一步研究p2082r1之后,从其上下文来看,“聚合元素”一词似乎是指聚合类型的元素而不是聚合的元素。如果满足bullet [1.5]、[1.6]、[1.7],则ei将成为聚合元素。然而,如果这些bullet都不符合要求,那么ei会是什么呢?这里似乎没有明确定义。
ei
将是数组的元素,其中数组是C的子聚合体。这似乎有点模糊。 - xmh0511