2013-05-26 93 views
15

此代碼中發生了什麼?很混亂。- >函數原型意味着什麼?

#include <utility> 

struct check 
{ 
    template <typename T> 
    auto foo() -> decltype(std::declval<T>().value, void()) 
    { 
     static_assert(T{}.value == 10, "Incorrect value"); 
    } 
} var; 

int main() 
{ 
    struct apple 
    { 
     int value{10}; 
    }; 

    var.foo<apple>(); 
} 

具體來說,它具有的部分->及其後的所有內容。

+2

- >是尾隨返回類型。 'declval'是這個班級的一個實例。 'decltype'找到編譯時表達式的類型。 'static_assert'是一個編譯時斷言。把它們拼湊在一起的時間:) – chris

+3

含糊不清的標題不會對其他有相同問題的人有用。 –

+1

@RiaD:雖然標題編輯更有幫助,但它仍然不準確 - 他似乎在詢問特定用途。 –

回答

10

讓我們一點一點地經歷。

auto foo() -> decltype(std::declval<T>().value, void()) 

這是一個尾隨返回類型。允許使用參數,但這裏沒有必要。我想這是寫得更清晰。 decltype找到裏面的表達式的類型,但該表達式實際上沒有被評估。 std::declval用於創建傳遞給它的類型的實例。這裏使用逗號運算符來使總體返回類型void,因爲逗號運算符評估左側,將其拋出,評估右側並返回該結果。

第一部分創建了一種SFINAE(儘管我從來沒有見過它是這樣使用的)。例如,如果您的foo的過載與value2的過載相同,而不是value,則不會含糊不清。我的意思是here。將其與this one進行比較,其返回類型爲void,並導致錯誤。

static_assert(T{}.value == 10, "Incorrect value"); 

此行確保如果沒有的話,會產生與文本編譯器錯誤的T值初始化實例都有value成員有值10。

} var; 

這只是該類使用的全局對象。

struct apple 
{ 
    int value{10}; 
}; 

這是一個樣本類來測試它。它有一個value成員,該成員在值初始化的實例中也是10(也是默認初始化的)。

var.foo<apple>(); 

這只是調用函數。

+0

當我做'struct grape {}; var.foo ();'它給我一個錯誤。我怎麼能讓它默默地失敗? –

+0

@MemyselfandI,你需要有一個適用於葡萄等結構的'foo'版本。問題是你必須確保用'apple'調用它並不含糊。我會盡力準備一個例子。 – chris

+0

@MemyselfandI,非常感謝Xeo,[你在這裏](http://coliru.stacked-crooked.com/view?id=200ce7dd4c270d3bfdea6df8628f6e4e-8a676986784bd3a58ce3ec015645a41f)。這是你可以根據類型是否具有'value'數據成員來實現'foo'的地方。 – chris