2013-09-10 34 views
17

这受到Andrei Alexandrescu的post的启发。每种方式初始化表达式的优缺点有哪些?

用以下方法初始化表达式的pro和con有什么作用?我应该什么时候比另一个更喜欢一个?

auto v = expr; 
T v = expr; 
auto v(expr); 
T v(expr); 
auto v { expr }; 
T v {expr}; 
+3

每当它更容易阅读。例如。 'auto p = std :: make_shared (1,2,3);'。任何时候,一个描述函数都会返回一些很难表明的东西 - 迭代器,引用包装器,弱指针锁等。 –

+0

所有依赖于'T'和'expr'。例如如果'T'是'int',我不会使用'auto'。 –

+0

@KerrekSB对,但一些C++专家同意了上面最丑陋的语法之一是更可取的,特别是'auto v {expr}; '我想知道为什么 – pyCthon

回答

5

auto v = expr; T v = expr;是不错,但在汽车的版本可能是很难理解的expr类型。

例如,在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; 
     ^

...

auto v { expr };几乎总是错的,因为五世的类型变得initializer_list代替T.

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

+1

'auto v {expr}'几乎总是错的;它给你一个'std :: initializer_list '而不是'T'。 – Simple

+0

哦拍你说得对。我会更新我的帖子以反映这一点。 –

+0

这很有趣,Herb Sutter和Andrei显然有相反的意见,因为 'auto v {expr}'实际上是选择的最佳方式。 – pyCthon

5

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

auto在类型很难打字时很有用,类型从上下文中清楚。但是auto x = 12;很难说是签名还是未签名,例如[我不知道规则,可能签名]。

+0

'auto x = 12;'是'signed int','auto x = 12u;'是'unsigned int' –

+1

@xlc:'auto y = 123456789876'? '汽车z = 0x1234'? :-) –

+0

'y'将在LP64平台上“长”,在LLP64上“长”。 'z'是'unsigned int'。也许我知道规则有点太好了。 @KerrekSB – bames53

2

我认为,不必使用自动为

auto x = 12332; // or 
auto z = 0xffff; // 

因为,

auto x = 12332; // type is 'int' 
auto x2 = 0xffff // type is 'int' 
auto y = 0xffffffff; // 8 fs, type is unsigned int 
auto z = 0xfffffffff;// 9 fs, type is long long 
auto t = 0xffffffffffffffff; // 16 fs, type is unsigned long long. 

但是,你可以使用

auto size = array.size(); 
2

这是一个相当困难的问题。

有两个不同的问题。

首先是是否使用类型推导,即使用auto说明符或明确指定类型。一般来说,我会说这是最好明确指定类型,以帮助可读性,除非该类型是冗长繁琐(例如迭代器):

auto it = vec.begin(); 

,或者类型是显而易见的初始化:

auto pfoo = new Foo(x,y,z); 

或者如果你不关心可读性。

第二种是使用什么类型的初始化。有直接初始化,复制初始化和列表初始化 - 初始化的行为很大程度上取决于目标的类型。这些差异在C++标准的8.5节中描述。初始化出现在更多的地方,而不仅仅是简单的声明。初始化发生在参数传递,返回值,子表达式,语句条件,数组边界以及许多其他地方。这是你需要了解细节的一些东西,一些简短的总结不会削减它。

相关问题