2014-12-18 52 views
23

我想(想)我明白auto。同樣約decltype。然而,在C++ 14中,可以有一些像decltype(auto)這樣的暗含的東西作爲函數的返回類型。考慮以下幾點:爲什麼decltype(auto)會在這裏返回一個引用?

decltype(auto) foo() 
{ 
    int m = 1; 
    return m; 
} 

返回類型爲int,一切纔有意義。

然而,

decltype(auto) foo() 
{ 
    int m = 1; 
    return (m); 
} 

返回int&(即參照int)。

我絕對沒有想法爲什麼發生這種情況,爲什麼這些圓括號有什麼區別呢?希望有人能夠對此有所瞭解。

PS:我也標記爲C++,因爲有更多人檢查C++標籤,而不是C++14

+2

因爲'decltype((m))'也是一個左值參考。 – 0x499602D2 2014-12-18 23:18:46

+0

我這麼認爲,所以把括號括起來使它成爲左值?也就是說,如果我做'return(Foo())',它是否被認爲是返回對'Foo()'的引用? – vsoftco 2014-12-18 23:20:14

+1

@vsoftco否,「decltype(e)」的規則取決於「e」是否被括號括起來。這並不意味着在別處添加括號會產生這種影響 – 2014-12-18 23:22:34

回答

28

7.1.6.2 [dcl.type.simple]

  • 對於表達式e,通過decltype(e)中表示的類型定義如下:
    - 如果e是非隱含的id表達式或未隱含的類成員訪問(5.2.5),則decltype(e)是由e命名的實體的類型。如果沒有這樣的實體,或者如果e名稱是一組重載函數,則該程序是不合格的;如果e是x值,則decltype(e)是T & &,其中T是e的類型;如果e是左值,則decltype(e)是T &,其中T是e的類型;否則,如果e是左值,則decltype(e)是T &,其中T是e的類型;
    - 否則,decltype(e)是e的類型。
  • 在你的榜樣,你有這麼return (m)e(m)。這不是一個非私有的id表達式或類成員訪問,所以我們轉到第二個項目符號。這不是一個xvalue,所以我們去第三個子彈。這是一個左值,所以類型是T&,其中Tint

    +1

    現貨,我唯一不明白的是爲什麼把'(...)'變成'decltype'認爲它有一個左值 – vsoftco 2014-12-18 23:23:10

    +4

    'm'已經是一個左值,並且'(m)'也是一個左值。問題在於括號改變了'decltype'如何推斷它的類型。如果沒有雙括號,你只需得到'm'類型,用雙括號可以得到T &&或T&,這取決於'm'是左值還是右值(在你的例子中是左值) – 2014-12-18 23:25:00

    +0

    這就是我沒有得到的:在你的答案中的第一行:「如果e是一個未親密的......」暗示'decltype(m)'推導出'int'。第三行,「如果e是左值...」,則暗示'int&'。但是,在第一種情況下,'e'(或者'm'在我的情況下)也是一個左值,但是因爲它沒有括號被推導爲非參考?我得說這個標準有點混亂,但是這是怎麼回事? – vsoftco 2014-12-18 23:28:53