【问题标题】:Uniform and Value-initialization [duplicate]统一和值初始化
【发布时间】:2015-04-01 20:10:30
【问题描述】:

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

所以...当我定义:

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

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

【问题讨论】:

  • 嗯,我认为这是因为B 不是一个聚合,但据我所知,它实际上似乎满足要求。这简直是​​不平凡的。
  • 请注意,Ideone.com 上的“C++14”是 g++-4.9.2,它不符合 C++14(正如此编译错误所证明的那样!)

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


【解决方案1】:

在 C++11 规则下,B 不是聚合类型。 C++11 [dcl.init.aggr]/1:

聚合是一个数组或一个类(第 9 条),没有用户提供的构造函数 (12.1),没有 brace-or-equal-initializers对于非静态数据成员 (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)。

具有相当直接的语义:没有指定初始化器的字段从它们的 brace-or-equal-initializer(如果有)进行初始化,否则使用 {} [dcl. init.aggr]/7:

如果列表中的 initializer-clauses 少于聚合中的成员,则每个未显式初始化的成员都应从其 brace-or-equal-initializer 或者,如果没有 brace-or-equal-initializer,则从空的初始化程序列表 (8.5.4) 中获取。

因此,您的程序是有效的 C++14 (DEMO)。从本质上讲,C++11 中禁止 brace-or-equal-initializer 是 C++14 纠正的错误。

【讨论】:

  • 非常感谢您的详细解答!我想我应该用另一个 c++14 编译器进行测试以确保...
猜你喜欢
  • 2020-03-18
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多