Ray*_*Ray 43 c++ initialization c++11
在C++参考页说,()是用于值初始化,{}为值和骨料和列表的初始化.那么,如果我只想要值初始化,我会使用哪一个?() 要么 {}?我问,因为在Bjarne本人的"A Tour of C++"一书中,他似乎更喜欢使用{},即使是价值初始化(例如参见第6页和第7页),所以我认为总是好的做法使用{},即使是值初始化.但是,我最近被以下的bug严重咬了.请考虑以下代码.
auto p = std::make_shared<int>(3);
auto q{ p };
auto r(p);
Run Code Online (Sandbox Code Playgroud)
现在根据编译器(Visual Studio 2013),q有类型std::initializer_list<std::shared_ptr<int>>,这不是我想要的.我实际想要的q实际上是什么r,是什么std::shared_ptr<int>.因此,在这种情况下,我应该不使用{}进行初始化值,但使用().鉴于此,为什么Bjarne在他的书中似乎仍然倾向于使用{}进行价值初始化?例如,他double d2{2.3}在第6页的底部使用.
要明确回答我的问题,我应该何时使用(),何时应该使用{}?这是语法正确性还是良好的编程习惯问题?
哦,呃,如果可能的话,请说明文.
编辑:似乎我略微误解了价值初始化(见下面的答案).然而,上述问题仍然存在.
Gal*_*lik 25
Scott Meyers在他的" 有效的现代C++"一书中对两种初始化方法的区别有很大的说法.
他总结了这两种方法:
大多数开发人员最终选择一种分隔符作为默认设置,仅在必要时使用另一种分隔符.Braces-by-default人们被他们无与伦比的广泛适用性,禁止缩小转换以及他们对C++最令人烦恼的解析的免疫力所吸引.这些人理解在某些情况下(例如,创建
std::vector具有给定大小和初始元素值的a),需要括号.另一方面,go-parentheses-go crowd将括号作为默认参数分隔符.他们被C++ 98语法传统的一致性所吸引,它避免了自动推断的-std :: initializer_list问题,并且他们的对象创建调用的知识不会被std::initializer_list构造函数无意地重置.他们承认有时只会使用大括号(例如,在创建具有特定值的容器时).没有人认为任何一种方法都比另一方更好,所以我的建议是选择一种方法并始终如一地应用它.
R S*_*ahu 24
这是我的意见.
使用auto类型说明符时,使用起来更清晰:
auto q = p; // Type of q is same as type of p
auto r = {p}; // Type of r is std::initializer_list<...>
Run Code Online (Sandbox Code Playgroud)
使用显式类型说明符时,最好使用{}而不是().
int a{}; // Value initialized to 0
int b(); // Declares a function (the most vexing parse)
Run Code Online (Sandbox Code Playgroud)
人们可以使用
int a = 0; // Value initialized to 0
Run Code Online (Sandbox Code Playgroud)
但是,表格
int a{};
Run Code Online (Sandbox Code Playgroud)
可用于初始化用户定义类型的对象的值.例如
struct Foo
{
int a;
double b;
};
Foo f1 = 0; // Not allowed.
Foo f1{}; // Zero initialized.
Run Code Online (Sandbox Code Playgroud)
首先,似乎有一个术语混淆.你所拥有的不是价值初始化.当您不提供任何显式初始化参数时,会发生值初始化.int x;使用默认初始化,x将不指定值.int x{};使用值初始化,x将是0.int x();声明一个函数 - 这就是为什么{}首选值初始化.
您显示的代码不使用值初始化.随着auto,最安全的方法是使用复制初始化:
auto q = p;
Run Code Online (Sandbox Code Playgroud)
还有另一个重要区别:大括号初始化程序要求给定类型实际上可以保存给定值.换句话说,它禁止缩小值,如舍入或截断.
int a(2.3); // ok? a will hold the value 2, no error, maybe compiler warning
uint8_t c(256); // ok? the compiler should warn about something fishy going on
Run Code Online (Sandbox Code Playgroud)
与大括号初始化相比
int A{2.3}; // compiler error, because int can NOT hold a floating point value
double B{2.3}; // ok, double can hold this value
uint8_t C{256}; // compiler error, because 8bit is not wide enough for this number
Run Code Online (Sandbox Code Playgroud)
特别是在使用模板的泛型编程中,因此当底层类型对输入值执行意外操作时,应使用大括号初始化来避免令人讨厌的意外.
| 归档时间: |
|
| 查看次数: |
3207 次 |
| 最近记录: |