direct aggeregate initialisation
C++20引入了direct aggeregate initialisation,那么它和传统的list aggeregate initialisation有啥区别。
我们用例子来说明:
比如array的aggeregate initialisation
int a[]{1,2,3};
int a[](1,2,3);
struct A{
int i;
bool b;
};
A aa{42,true};//list aggeregate init
A ab(42,true);//direct aggeregate init
可以看到,可以使用小括号做direct aggeregate init,而传统的大括号init称为list aggeregate init.
direct aggeregate init 和list aggeregate init的区别。
direct aggeregate init 可以做窄转化
A ac{42.1, true};//fail
A ad(42.1, true);
direct aggeregate init 使得容器的emplace_back可以使用aggeregate初始化。
vector<A> v;
v.emplace_back(42,true);//valid in C++20 //unvalid in C++17
direct aggeregate init可以很方便的用在宏中
assert( A {1,true}.b )//fail
assert( A (1,true).b )
然而direct aggeregate 不能做递归展开
struct AA{
A f;
A s;
};
AA {1,true,2,false};
AA (1,true,2,false);//fail
direct aggeregate init不能延长右值引用成员的生存期
struct A{
int && i;
double d;
};
A a{1,2};//ok
A b(1,2);//dangling reference
小括号内是空时,不会做direct aggeregate init
struct Bar{
explicit Bar()=default;
};
struct S{
int a;
Bar b;
};
int main(){
//fail
//S c= S{1,{}};
//S d= S(1,{});
//S e= S{1};
//S f = S(1);
//S g=S{};
S h = S();
}
对象c d e f g初始化失败因为aggeregate init时要对成员b调用Bar的copy initialisation将调用Bar的构造函数而Bar的构造函数却是explicit的,不能做copy initialisation.
然而h却成功了,因为这时小括号内是空的,将使用zero initialisation而永不会使用aggeregate init.
Posted 2022-06-03