`Object obj(args ...)`和`Object obj {args ...}`有什么区别?

xml*_*lmx 7 c++ oop constructor uniform-initialization c++11

Scott Meyers 撰写的Effective C++ 11草案规定:

在创建对象时区分()和{}

Object obj(args...)和之间有什么区别Object obj{args...}?为什么斯科特这么说.

更新:

问题如何使用C++ 11统一初始化语法?请问如何,这个问题问为什么.

UPDATE2:

我发现以下链接很有帮助,完全回答了这个问题:

https://softwareengineering.stackexchange.com/questions/133688/is-c11-uniform-initialization-a-replacement-for-the-old-style-syntax

Pra*_*ian 5

Object obj(args...)和之间有什么区别Object obj{args...}

第一种是直接初始化,而第二种是直接列表初始化.这在两个不同的部分提到:

§8.5/ 16 [dcl.init]

表单中发生的初始化

 T x(a);
 T x{a};
Run Code Online (Sandbox Code Playgroud)

new表达式(5.3.4)中,static_cast表达式(5.2.9),函数表示法类型转换(5.2.3)以及基本和成员初始化器(12.6.2)称为直接初始化.

§8.5.4/ 1 [dcl.init.list]

列表初始化是从braced-init-list初始化对象或引用.这样的初始化程序称为初始化程序列表,列表的逗号分隔的初始化程序子句称为初始化程序列表的元素.初始化列表可以为空.列表初始化可以在直接初始化或复制初始化上下文中进行; 直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化.


两者之间存在一些差异:

  • 如果正在构造的类型具有带initializer_list参数的构造函数,则direct-list-initialization将始终支持该构造函数.只有initializer_list构造函数不可行时才会考虑其他构造函数.§13.3.1.7/ 1 [over.match.list]

  • direct-list-initialization不允许缩小参数列表中的转换.§8.5.4/ 3 [dcl.init.list]

  • 如果正在初始化的类型是聚合,则direct-list-initialization将执行聚合初始化.§8.5.4/ 3 [dcl.init.list]

  • braced-init-list元素的评估顺序是从左到右.§8.5.4/ 4 [dcl.init.list]

  • 您可以通过使用直接列表初始化来避免最令人烦恼的解析

 

  struct foo{};
  struct bar 
  {    
    bar(foo const&) {}
  };

  bar b1(foo()); // most vexing parse
  bar b2(foo{}); // all 3 of the following construct objects of type bar
  bar b3{foo()};
  bar b4{foo{}};
Run Code Online (Sandbox Code Playgroud)