2015-09-08 41 views
15

我讀this question on isocpp FAQ here,這個問題是解釋如何編寫的返回類型???這句「decltype(*(T *)(0)**(U *)(0))」是什麼意思?

template<class T, class U> 
??? mul(T x, U y) 
{ 
return x*y; 
} 

我明白最簡單的方式就是寫auto mul(T x, U y) -> decltype(x*y),但是問題也給出了另一種方式,是通過更換???decltype(*(T*)(0)**(U*)(0))。但我不完全明白這是什麼decltype(*(T*)(0)**(U*)(0))真的在做什麼,它似乎是宣佈一個臨時指針T*並初始化爲零,然後解引用指針,然後乘以相同的對手類型U,我的理解是正確的嗎?

但爲什麼要使用指針?我認爲decltype(T(0)*U(0))decltype(T{0}*U{0})也應該工作。

+2

即假定'T '和'U'有一個構造函數,它接受一個整數參數。指針的方式不會假設「T」和「U」的構造函數。 –

+4

請注意,它不是未定義的行爲,因爲它[在未評估的上下文中](http://stackoverflow.com/a/28723577/1708801) –

回答

20
decltype(*(T*)(0)**(U*)(0)) 

我們分了起來:

(T*)(0) //cast a null pointer to a T* 
*(T*)(0) //dereference, giving a T 

(U*)(0) //cast a null pointer to a U* 
*(U*)(0) //dereference, giving a U 

(*(T*)(0)) * (*(U*)(0)) //the result of multiplying a U and a T 

decltype(T(0)*U(0))相當於只有TU有構造採取單一int(或東西可以從一個整數文字隱式轉換)。

標準庫已經有一個std::declval更清潔的方式來做到這一點:

decltype(std::declval<T>() * std::declval<U>()) 
0

這的確容易出錯。

在您的解決方案中,您基本上認爲construcor可以獲得0作爲參數,但情況可能並非如此。

的片段基本上投NULL一些T對象的指針,然後拉出T*運營商,現在我們還剩下基本上decltype({T object}*{U object})它假定在編譯時,該decltype將由真正的類型和運行時更換將不會有指針。但是這個代碼非常醜陋,不可維護。

更好的解決方案是使用C++ 11 std::result_of
typename std::result_of<declval<T>()*declval<U>()>::type

declval確實類似於*(T*)(0)僅返回r值參考(意味着T&&)東西

+4

這不是'result_of'的目的,它不會在這裏編譯。 – Barry