统一和值初始化

时间:2015-04-01 20:10:30

标签: c++ c++11 initialization c++14

我尝试对构造函数值初始化的成员使用值初始化(我不知道我是否真的使用了良好的术语......)

所以......当我定义:

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&&'

有什么区别,概念方面? 非常感谢!

1 个答案:

答案 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纠正的一个错误。