2013-09-10 41 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節中描述。初始化出現在更多的地方,而不僅僅是簡單的聲明。初始化發生在參數傳遞,返回值,子表達式,語句條件,數組邊界以及許多其他地方。這是你需要了解細節的一些東西,一些簡短的總結不會削減它。

相關問題