列表初始化(使用花括号)有什么优点?

新手上路,请多包涵
MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);

为什么?

原文由 Oleksiy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 992
2 个回答

基本上是从 Bjarne Stroustrup 的 “The C++ Programming Language 4th Edition” 复制和粘贴:

列表初始化 不允许缩小 (§iso.8.5.4)。那是:

  • 一个整数不能转换为另一个不能保存其值的整数。例如,允许从 char 到 int,但不允许从 int 到 char。
  • 浮点值不能转换为另一种不能保存其值的浮点类型。例如,允许双精度浮点数,但不允许双精度浮点数。
  • 浮点值不能转换为整数类型。
  • 整数值不能转换为浮点类型。

例子:

 void fun(double val, int val2) {

    int x2 = val;    // if val == 7.9, x2 becomes 7 (bad)

    char c2 = val2;  // if val2 == 1025, c2 becomes 1 (bad)

    int x3 {val};    // error: possible truncation (good)

    char c3 {val2};  // error: possible narrowing (good)

    char c4 {24};    // OK: 24 can be represented exactly as a char (good)

    char c5 {264};   // error (assuming 8-bit chars): 264 cannot be
                     // represented as a char (good)

    int x4 {2.0};    // error: no double to int value conversion (good)

}


= 优于 {} 的 唯一 情况是使用 auto 关键字来获取由初始化程序确定的类型。

例子:

 auto z1 {99};   // z1 is an int
auto z2 = {99}; // z2 is std::initializer_list<int>
auto z3 = 99;   // z3 is an int


结论

除非您有充分的理由不这样做,否则首选 {} 初始化而不是替代方法。

原文由 Oleksiy 发布,翻译遵循 CC BY-SA 4.0 许可协议

关于使用列表初始化的优点已经有了很好的答案,但是我个人的经验法则是尽可能不要使用花括号,而是让它依赖于概念含义:

  • 如果我正在创建的对象在概念上包含我在构造函数中传递的值(例如容器、POD 结构、原子、智能指针等),那么我正在使用大括号。
  • 如果构造函数类似于普通的函数调用(它执行一些或多或少复杂的操作,这些操作由参数参数化),那么我使用的是普通的函数调用语法。
  • 对于默认初始化,我总是使用花括号。

一方面,这样我总是确定对象被初始化,不管它是一个“真实的”类,它有一个无论如何都会被调用的默认构造函数,还是一个内置/POD类型。其次,在大多数情况下,它与第一条规则一致,因为默认初始化对象通常表示“空”对象。

根据我的经验,这个规则集可以比默认使用花括号更一致地应用,但是当它们不能被使用或具有与带括号的“正常”函数调用语法不同的含义时,必须明确记住所有异常(调用不同的重载)。

例如,它非常适合标准库类型,例如 std::vector

 vector<int> a{10, 20};   //Curly braces -> fills the vector with the arguments

vector<int> b(10, 20);   //Parentheses -> uses arguments to parametrize some functionality,
vector<int> c(it1, it2); //like filling the vector with 10 integers or copying a range.

vector<int> d{};      //empty braces -> default constructs vector, which is equivalent
                      //to a vector that is filled with zero elements

原文由 MikeMB 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题