Dun*_*ter 5 c++ coding-style initialization c++11
在初始化自动管理的简单变量而不是通过赋值时,有几种不同的风格。我想知道是否有任何特定的理由偏爱一个而不是另一个,或者这只是一个风格问题。
使用括号很有吸引力,因为它感觉类似于实例化一个对象
double answer(42.0);
ComplexNumber i(0,1);
Run Code Online (Sandbox Code Playgroud)
虽然使用大括号很有吸引力,因为它感觉类似于初始化容器
double answer{42};
std::vector<double> i{0,1};
double i2[] = {0,1};
Run Code Online (Sandbox Code Playgroud)
有什么特别的理由偏爱一种风格而不是另一种风格吗?
看这里:GotW #1:变量初始化。这是 H. Sutter 答案的详细描述。
\n\nH. Sutter 上面谈到了变量初始化的新旧风格的一般意义。
\n\n下面根据您的起始主题上下文显示了本文的快速摘要。
\n\n这对
\n\ndouble answer(42.0); // (1)\ndouble answer{42}; // (2)\nRun Code Online (Sandbox Code Playgroud)\n\n事实上,类似于下面的初始化示例:
\n\nwidget w(x); // (d)\nwidget w{x}; // (e)\nRun Code Online (Sandbox Code Playgroud)\n\n这些都是直接初始化。但请注意,该语法{x}会创建一个initializer_list. 如果widget有一个采用 的构造函数initializer_list,则首选该构造函数;否则,如果widget有一个采用任何类型的构造函数x(可能带有转换),则使用该构造函数。
(2, e) 优于 (1, d) 有两个主要区别:
\n\nx是类型名称,则 (1, d) 是函数声明,即使x作用域中还存在命名的变量(见上文),而 (2, e) 绝不是函数声明。其次,语法 (2, e) 更安全,因为它不允许缩小(又名 \xe2\x80\x9clossy\xe2\x80\x9d)转换,而某些内置类型则允许这种转换。考虑:
\n\nint i1( 12.345 ); // ok: toss .345, we didn\'t like it anyway
int i2{ 12.345 }; // error: would be lossy implicit narrowing
下一对
\n\nComplexNumber i(0,1); // (3)\nstd::vector<double> i{0,1}; // (4)\nRun Code Online (Sandbox Code Playgroud)\n\n与复杂对象的初始化相关。两者看起来完全相同,但第二个可以帮助我们避免“令人烦恼的解析”,例如:
\n\nComplexNumber w( real(), img() ); // oops, vexing parse \nRun Code Online (Sandbox Code Playgroud)\n\n除此之外,这种方式使代码更加清晰(如果我们使用initializer_list,初始化会更清晰),而且在某些情况下可以减轻语法,例如:
draw_rect({ origin, selection }); // C++11\nRun Code Online (Sandbox Code Playgroud)\n\nSutter 的原则是:更喜欢使用 初始化{ },例如vector<int> v = { 1, 2, 3, 4 };或auto v = vector<int>{ 1, 2, 3, 4 };,因为它\xe2\x80\x99 更一致、更正确,并且完全避免了了解旧式陷阱。在单参数情况下,您更愿意只看到符号=,例如int i = 42;和auto x = anything; 省略大括号就可以了。
我们可以使用 () 初始化来显式调用特殊构造函数。
\n| 归档时间: |
|
| 查看次数: |
1500 次 |
| 最近记录: |