初始化表达式的每种方式的优缺点是什么?

pyC*_*hon 17 c++ c++11 c++14

这是受到Andrei Alexandrescu的一篇文章的启发.

使用以下方法初始化表达式的专家和概念是什么?我什么时候应该更喜欢一个?

auto v = expr;
T v = expr;
auto v(expr);
T v(expr);
auto v { expr }; 
T v {expr};
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 15

auto v = expr;
auto v(expr);
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您不知道类型expr并希望保持通用,或者在您的代码中,绝对清楚什么类型expr具有(在上面的行中的定义等),这样auto就不会增加混淆.

初始化的形式,parens与否,是无关紧要的(仅与语言律师有关,因为存在细微差别).使用你觉得更舒服的东西.


T v = expr;
T v(expr);
Run Code Online (Sandbox Code Playgroud)

如果在你的代码中不清楚是什么expr(定义太远,等等..),或者如果你不知道类型expr但希望v属于该类型T.如果你想继续使用"expr"所具有的"种类值"(即if expr是字符串并且T是字符串类型),请使用第一种形式.如果您构建了一种全新的值(即a Widget,并且expr是窗口小部件的颜色),请使用第二种形式.


auto v { expr }; 
Run Code Online (Sandbox Code Playgroud)

永远不要在当前的C++中使用它(可能在未来几年内).它将宣布vstd::initializer_list<TypeOfExpr>.如果需要,请直接使用该类型并将其写出.它太过微妙了(而且有超越C++ 14的提议要改变这个事实,所以希望你可以用C++ 17或类似的东西来写这个).


T v {expr};
Run Code Online (Sandbox Code Playgroud)

如果你想保护自己免受缩小转换(即从去1000char意外),或者如果你想初始化一个具有初始化列表构造函数的类,或者如果你有其中的要初始化的集合成员(S)使用此表格.或者,如果您正在处理初始化列表构造函数,聚合或简单的非类类型,则可以使用以下内容

T v = { expr };
Run Code Online (Sandbox Code Playgroud)

不会用它来调用任意构造函数.我会使用以下表格

T v(expr);
Run Code Online (Sandbox Code Playgroud)

但是,也有人喜欢使用括号形式.我想知道我的代码是做什么的,因此当我想调用一个构造函数,并且不想随意进行聚合或列表初始化构造函数调用时,我使用parens而不是braces. 


Nic*_*mot 5

auto v = expr; T v = expr;很好,但在自动版本中可能很难理解其类型expr.

例如,in auto x = snafuscate();,是什么类型x

在存在歧义的情况下,最好明确声明右侧的类型: auto x = Gadget { snafuscate() };

...

auto v(expr);并且T v(expr);是一个坏主意,因为有效expr也可以理解为函数指针.

此代码无法编译:

int main()
{
    int x(int());
    return x + 3;
}

prog.cpp:4:11: error: invalid conversion from ‘int (*)(int (*)())’ to ‘int’ [-fpermissive]
return x + 3;
         ^
Run Code Online (Sandbox Code Playgroud)

...

auto v { expr }; 几乎总是错的,因为v的类型变成了initializer_list而不是T.

有关汽车的最佳实践,请参阅:http://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/


Mat*_*son 5

除了含义不同的情况(例如vector<int> v(12),没有给出一个值为12的向量),编译器应该为上述所有内容提供相同的内容,而且实际上只是个人偏好决定哪个是"更好".

auto当类型难以键入时类型很有用,并且类型从上下文中清楚.但auto x = 12;很难说它是签名还是未签名,例如[我不知道规则,可能签名].