C++ 讨论:使用 =、{} 和 () 作为初始值设定项,我应该使用哪一个?

C++ Discussion: Use of =, {}, and () as initializers, Which one should I use?

在阅读 isocpp 的 C++ 核心指南时,我读完了 this 部分。到目前为止,我已经在我阅读的一些 C++ 代码中看到了这些方法。例如: () 在构造函数初始化列表中初始化数据字段时被使用,即使是 primitive 类型,我也看到它在本地使用。有些使用 {} 来初始化变量。而其他人则使用此 =。我不知道它们之间有什么区别。我的意思是他们是否实现了相同的目标,只是风格不同,或者它们具有不同的含义。谁能解释一下!

= 和初始化程序中的大括号之间的区别几乎不存在。如果您 运行 有所不同,那么您正在做一些奇怪的事情或在 C++14 之前的编译器上。

{}()的主要区别在于{}不进行隐式转换,例如非explicit转换构造函数和转换运算符,改变在有符号和无符号类型之间,以及扩大或缩小整数和浮点宽度。因此,我听到的一般建议是尽可能使用 {},以避免意外的类型转换。

作为 C++11 标准的一部分,引入了大括号 {} 的通用用法。这里重要的 属性 是 {} 初始化不允许缩小转换。例如

double d = 1.7789856453427678;
int a{d}; //Compile time error - value of d will not fit in a
int a(d); //ok - a is 1
int a = d; //ok - a is 1

因此大括号 {} 初始化是编写更健壮代码的首选方法。

您可能对有关此主题的录音谈话感兴趣 - 关于在 C++(11 及更高版本)中进行统一初始化 "work" 的近期历史:

CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++”

演讲结尾的一些片段:

  • Google,在他们的 Abseil 倡议中,拒绝尝试 "convert" 人们一致使用花括号初始化。因此,当初始化主动应用某些逻辑时,他们坚持 adopting/recommending 等于 "direct" 初始化和括号。 Nicolai 不赞成这种做法。
  • Nicolai建议:努力改变我们的习惯,更喜欢大括号初始化。现在比以前好多了

PS - 这个演讲可能也很有趣:

Core C++ 2019 :: Timur Doumler :: Initialisation in modern C++

更多的是调查不同类型初始化的复杂性(而且有很多!)