2014-06-20 18 views
3

我有以下代碼:與詮釋與論證通過INT &&函數初始化

#include <type_traits> 

struct TType 
{ 
    int a = 0; 

    bool operator() (int&) 
    { 
     return true; 
    } 
}; 

int main() 
{ 
    static_assert(std::is_same<decltype(std::declval<TType>()(std::declval<int>())), bool>::value, "wtf?"); 
    return 0; 
} 

如果我嘗試使用g編譯它++ - 4.8.2然後我收到一個錯誤:

main.cpp:321:82: error: no match for call to ‘(JetPlane) (int)’ 
static_assert(std::is_same<decltype(std::declval<JetPlane>()(std::declval<int>())), bool>::value, "wtf?"); 
                       ^
main.cpp:265:8: note: candidate is: 
struct JetPlane 
    ^
main.cpp:279:7: note: bool JetPlane::operator()(int&) 
bool operator() (int&) 
    ^
main.cpp:279:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’ 

我不瞭解note: no known conversion for argument 1 from ‘int’ to ‘int&’一行。所以,問題是:爲什麼G ++解釋返回std::declval<int>()型像int,雖然標準:: declval聲明看起來不就行了int&&

template< class T > 
typename std::add_rvalue_reference<T>::type declval(); 

據我所知,我們會禁止綁定int&&int。但爲什麼然後編譯器不打印:note: no known conversion for argument 1 from ‘int’ to ‘int&’行。可能是我不明白的東西和編譯器的變化莫名其妙地返回std::declval<int>()的類型從int&&intstd::declval<TType>()(std::declval<int>())

謝謝你的幫忙!

+0

'int &&'無法綁定到'int&'。 – Simple

+0

是的,我明白這一點。但是,爲什麼那麼編譯器不打印:沒有已知的轉換從參數1「詮釋&&」到「廉政和」 – rbtrht

+2

我想這是由於遺留原因。這是類型'int'的右值,這對年齡意味着類型'int',所以這是錯誤的報告。是的,你的情況是類型INT''&&,但是這仍然是一個'int'右值。 – Angew

回答

5

問題是,您無法將xvalue綁定到非常量左值引用。

讓我們看看錶達

std::declval<int>() 

std::declval<int>返回類型的確是int&&。因此,上述表達式是int類型的xvalue表達式。請注意,在C++中,表達式從不具有引用類型。

但是你的運營商

bool operator() (int&) 

通過非const左值referenece接受其參數。如果您更改perameter類型const int&,即

bool operator() (const int&) 

一切都應該正常工作。

+0

謝謝。那是我懷疑我不知道的:「請注意,在C++中,表達式從來沒有引用類型。」這個[這裏]的好解釋(http://stackoverflow.com/questions/17241614/in-c-what-expressions-yield-a-reference-type-when-decltype-is-applied-to-them) – rbtrht

+0

+ 1由MWid清楚地分析 – Solkar

0

您不能使用右值引用來初始化左值引用。混亂的一點是,T&&意味着在不同的上下文不同的事情:

  • T&&用於定義對象時,右值引用可以被綁定到一個rvalue但定義對象實際上是它可以結合到一個左值左值參考當T&&用於聲明一個函數的含義是,右值引用被返回它的行爲,用於所有目的一樣的臨時的,因此返回類型
  • ,不能被綁定到一個左值參考。類型T&&被視爲臨時T用於重載解析的所有目的,看起來這是編譯器報告的內容。
+2

OP問爲什麼'std :: declval ()'是'int',而不是'int &&'。 – ikh

+0

爲什麼鍵入'T &&'被視爲'T',如果這些返回類型的函數?在我看來這是不正確的,因爲如果'T &&'返回類型,那麼函數返回'xvalue',如果'T'是返回類型,那麼函數返回'prvalue'。 – rbtrht

+0

@ikh:好的,事實並非如此。它只是恰好被視爲錯誤消息,我認爲你不能檢測到這種差異,當然不是'int'。對於任意類型,您可能能夠基於被調用的移動構造函數來檢測差異(儘管其中一個可能會被忽略)。 –