我尝试对构造函数值初始化的成员使用值初始化(我不知道我是否真的使用了良好的术语......)
所以......当我定义:
struct A
{
int a_;
};
我可以使用:
A a{5};
assert(m.a_==5);
但是,如果我想使用成员大括号初始化程序和初始化列表构造函数
struct B
{
int b_ {1};
};
这不编译(c ++ 14:http://ideone.com/MQ1FMU):
B b{2};
这是错误:
prog.cpp:19:7: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)'
B b{2};
^
prog.cpp:19:7: note: candidates are:
prog.cpp:10:8: note: constexpr B::B()
struct B
^
prog.cpp:10:8: note: candidate expects 0 arguments, 1 provided
prog.cpp:10:8: note: constexpr B::B(const B&)
prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'const B&'
prog.cpp:10:8: note: constexpr B::B(B&&)
prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'B&&'
有什么区别,概念方面? 非常感谢!
答案 0 :(得分:2)
在C ++ 11规则下,B
不是聚合类型。 C ++ 11 [dcl.init.aggr] / 1:
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有大括号或等于初始值对于非静态数据成员(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。
B
只有默认构造函数,因此无法从 braced-initializer-list {2}
初始化。
C ++ 14允许聚合中的非静态数据成员使用 brace-or-equal-initializers 。 N4140 [dcl.init.aggr] / 1:
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。
使用相当直接的语义:没有指定初始值设定项的字段从大括号或等号初始化程序初始化(如果有),否则用{}
初始化[ dcl.init.aggr] / 7:
如果列表中的 initializer-clauses 少于聚合中的成员,那么未显式初始化的每个成员都应从其 brace-or-equal-initializer <初始化< / em>或者,如果没有 brace-or-equal-initializer ,则从空的初始化列表(8.5.4)开始。
您的程序因此是有效的C ++ 14(DEMO)。基本上,在C ++ 11中禁止大括号或等于初始化是C ++ 14纠正的一个错误。