MyClass a1 {a}; // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
Run Code Online (Sandbox Code Playgroud)
为什么?
我在SO上找不到答案,所以让我回答一下我自己的问题.
以下是在C++ 11中初始化变量的两种方法:
T a {something};
T a = {something};
Run Code Online (Sandbox Code Playgroud)
我在所有可以想到的场景中测试了这两个,但我没有发现差异.这个答案表明两者之间存在细微差别:
对于变量,我在这些
T t = { init };或T t { init };样式之间没有太多关注,我发现差异很小,最坏的情况只会导致有关滥用显式构造函数的有用的编译器消息.
那么,两者之间有什么区别吗?
更新
我已经通过链接(例如何时使用大括号括起来的初始化程序?)何时应该使用{}大括号初始化,但是当我们应该使用括号( )与初始化{ }语法来初始化C++中的对象时,没有给出信息./ 14?什么标准的做法,建议使用()过{}?
在极少数情况下,例如vector<int> v(10,20);或auto v = vector<int>(10,20);,结果是std::vector10个元素.如果我们使用大括号,结果是std::vector2个元素.但这取决于调用者的用例:要么他/她想要分配10个元素的矢量还是2个元素?
目前正试图围绕 C++11 的统一初始化进行思考。我遇到了这个模棱两可的情况:考虑一个类,它可以由一个双参数构造函数或一个任意长度的初始化列表构造:
class Foo {
public:
Foo(int a, int b) {
std::cout << "constructor 1" << std::endl;
}
Foo(std::initializer_list<int>) {
std::cout << "constructor 2" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
遵循统一的初始化约定,我希望以下内容起作用:
Foo a (1, 2)印刷品constructor 1(废话)
Foo b {1, 2} 印刷 constructor 1
Foo c = {1, 2} 印刷 constructor 2
但是,编译器似乎将其解释Foo b {1, 2}为列表初始化,并调用构造函数 2。()当存在初始化列表构造函数时,语法是否是强制编译器考虑其他类型构造函数的唯一方法?
在关于初始化列表的讨论中,我理解Stroustrup基本上说用花括号的新构造语法应该是所有先前构造语法的一般替代:
X x1(); // most vexing parse ... doesn't work as intended
X x2(x1);
X x3 = x1;
X x4 = X();
Run Code Online (Sandbox Code Playgroud)
相反,新语法应该被统一使用,作为一种可能的替代品,你可以在每种情况下使用......再一次,这是我从他的谈话中得到的核心信息.也许我误解了他.
那么,问题是,这种语法有多通用?是否有可能永远不会在新的C++ 11代码中使用旧式构造,或者是否有必须还原的情况?
当我遇到以下错误时触发/激发了这个问题,我认为这是编译器中的错误(但我很乐意得到纠正).
struct X {};
int main() {
X x;
X& y{x}; // works with (x)
X& z{y}; // works with (y)
}
Run Code Online (Sandbox Code Playgroud)
哪个不能在g ++ 4.7.1上编译,也不在ideone的4.5.1上编译.
prog.cpp: In function 'int main()':
prog.cpp:5:9: error: invalid initialization of non-const reference of type 'X&' …Run Code Online (Sandbox Code Playgroud) 正如ideone所见:
cout << string(50, 'x'); // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
cout << string{50, 'x'}; // 2x
Run Code Online (Sandbox Code Playgroud)
WAT?
我已经发现50是ASCII'2',所以:
cout << static_cast<int>('2'); // 50
cout << static_cast<char>(50); // 2
Run Code Online (Sandbox Code Playgroud)
但就我而言,这就是我的意思.
这是否会导致针对C++ 11初始值设定项的可靠论据?
大多数人在用 C++ 或大多数其他语言声明字符串时,都会这样做:
std::string example = "example";
Run Code Online (Sandbox Code Playgroud)
但是我见过一些代码示例,其完成方式如下:
std::string example("example");
Run Code Online (Sandbox Code Playgroud)
对我来说,它似乎不必要地混淆了代码,特别是如果using std::string代码中的声明上方隐藏着一条语句,使其看起来像
string example("example");
Run Code Online (Sandbox Code Playgroud)
对于一些可能是代码库新手或来自其他语言的人来说,它几乎看起来像是一个方法或函数。
使用构造函数而不是赋值运算符是否有任何实际或基于性能的原因,或者是否只是个人喜好?