单变量初始化的 C++ 风格

标签 c++ c++11 coding-style initialization

<分区>

在初始化自动管理的简单变量时,除了通过赋值之外,还有几种不同的样式。我想知道是否有任何特定的理由偏爱其中一个,还是仅仅是风格问题。

使用括号很吸引人,因为它感觉类似于实例化一个对象

double answer(42.0);
ComplexNumber i(0,1);

虽然使用大括号很吸引人,因为它感觉类似于初始化容器

double answer{42};
std::vector<double> i{0,1};
double i2[] = {0,1};

是否有任何特别的理由偏爱一种风格而不是另一种风格?

最佳答案

看这里:GotW #1 : Variable Initialization .这是对H. Sutter 回答的详细描述。

H. Sutter 在上面谈到了变量初始化的新旧风格的一般意义。

根据您的起始主题上下文,下面显示了文章的简要提要。


这对

double answer(42.0); // (1)
double answer{42};  // (2)

其实类似于下一个初始化例子:

widget w(x);                // (d)
widget w{x};                // (e)

这些都是直接初始化。但是,请注意语法 {x}创建一个 initializer_list .如果widget有一个接受 initializer_list 的构造函数, 该构造函数是首选;否则,如果widget有一个采用任何类型的构造函数 x是(可能有转换),使用构造函数。

有两个主要区别使 (2, e) 优于 (1, d):

  • 首先,语法 (2, e) 是明确的并且避免了“令人烦恼的解析”。如果x是一个类型名称,那么 (1, d) 是一个函数声明,即使还有一个名为 x 的变量在范围内(见上文),而 (2, e) 永远不是函数声明。
  • 其次,语法 (2, e) 更安全,因为它不允许缩小(也称为“有损”)转换,否则某些内置类型会允许转换。考虑:

    int i1( 12.345 ); // ok: toss .345, we didn't like it anyway

    int i2{ 12.345 }; // error: would be lossy implicit narrowing

下一对

ComplexNumber i(0,1); // (3)
std::vector<double> i{0,1}; // (4)

与复杂对象的初始化有关。两者看起来完全一样,但第二个帮助我们避免“令人烦恼的解析”,例如:

ComplexNumber       w( real(), img() );       // oops, vexing parse 

除此之外,这样可以使代码更清晰(如果我们使用 initializer_list ,更清晰的是初始化), 并且,此外,在某些情况下减少语法,例如:

draw_rect({ origin, selection });                  // C++11

Sutter 准则是:更喜欢使用 { } 进行初始化,例如 vector<int> v = { 1, 2, 3, 4 };auto v = vector<int>{ 1, 2, 3, 4 }; ,因为它更一致,更正确,并且完全避免了必须了解旧式陷阱。在您希望只看到 = 的单参数情况下符号,例如 int i = 42 ;和 auto x = anything ;省略大括号是可以的。

我们可以使用 ()-initialization 来显式调用特殊构造函数。

关于单变量初始化的 C++ 风格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17112692/

相关文章:

java - 在 Java 中,类的方法冗余地返回类的修改后的全局字段是一种好的做法吗?

c++ - LNK2019 - 未解析的外部符号 C++

c++ - 使用 g++ 在终端中运行 .cpp 文件时出错

c++ - 函数正确执行后如何修复 Core Dumped 错误?

java - 如何在netbeans IDE中用java编写多行长方法调用

ruby - 仅在存在时修改 Ruby 散列中的值

c++ - 类定义和内存分配

c++ - 在 OpenGL 中渲染相机前的对象

c++ - vector 扩展和线程例程

C++ 类成员和延迟初始化