这是受到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++中使用它(可能在未来几年内).它将宣布v为std::initializer_list<TypeOfExpr>.如果需要,请直接使用该类型并将其写出.它太过微妙了(而且有超越C++ 14的提议要改变这个事实,所以希望你可以用C++ 17或类似的东西来写这个).
T v {expr};
Run Code Online (Sandbox Code Playgroud)
如果你想保护自己免受缩小转换(即从去1000到char意外),或者如果你想初始化一个具有初始化列表构造函数的类,或者如果你有其中的要初始化的集合成员(S)使用此表格.或者,如果您正在处理初始化列表构造函数,聚合或简单的非类类型,则可以使用以下内容
T v = { expr };
Run Code Online (Sandbox Code Playgroud)
我不会用它来调用任意构造函数.我会使用以下表格
T v(expr);
Run Code Online (Sandbox Code Playgroud)
但是,也有人喜欢使用括号形式.我想知道我的代码是做什么的,因此当我想调用一个构造函数,并且不想随意进行聚合或列表初始化构造函数调用时,我使用parens而不是braces.
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/
除了含义不同的情况(例如vector<int> v(12),没有给出一个值为12的向量),编译器应该为上述所有内容提供相同的内容,而且实际上只是个人偏好决定哪个是"更好".
auto当类型难以键入时类型很有用,并且类型从上下文中清楚.但auto x = 12;很难说它是签名还是未签名,例如[我不知道规则,可能签名].
| 归档时间: |
|
| 查看次数: |
1347 次 |
| 最近记录: |