2010-05-04 35 views
11

我:decltype,result_of或typeof?

class A { 
public: 
    B   toCPD() const; 

和:

template<typename T> 
class Ev { 
public: 
    typedef result_of(T::toCPD()) D; 

實例Ev<A>後,編譯器說:

meta.h:12:錯誤: 'T :: toCPD' 不是一個類型

既不decltype也不typeof工作。

+2

爲了大家的興趣,值得注意的是C++ 0x允許非靜態* data *成員使用相同的值。你*可以*例如'struct A {int a; }; decltype(A :: a * 3)b = 0;'已經在GCC4.5中。只要發生在C++ 0x中未評估的操作數中,就可以對非靜態數據成員執行任何操作。 – 2010-05-04 17:09:05

回答

31

由於任何導致你獲得取決於模板參數,typedef typename是必要設定的結果類型的元函數。

decltype是一個標準的C++ 11功能。它是一個「運算符」,它接受一個表達式並返回一個類型。

typedef typename decltype(T().toCPD()) D; // can't use T:: as it's nonstatic 

如果T()不是有效的(T不是默認-constructible)你會想declval這是一個函數,需要一個類型並返回類型的毫無意義的,無效的值。 declval只能用於未評估的上下文中,如decltype

typedef typename decltype(std::declval<T>().toCPD()) D; 

C++ 11之前,decltype是一個非標準擴展微軟的MSVC編譯器。標準化可能會改變它的行爲。


typeof是GCC的等效預C++ 11延伸像decltype,這也克隆在其他編譯器。 Here是來自GCC的文檔。該頁面沒有提供這些功能之間的比較,但是它指出typeof在使用標準模式(-std=c++YY,您應該總是做的)時必須調用__typeof__,它在C和C++中都是可用的。

爲了兼容C,__typeof__不會從glvalue表達式中解析引用類型。因此,它確實只適用於C.這可能解釋了爲什麼C++特性沒有繼承更明顯的名稱:GNU不願意犧牲向後兼容性,而Microsoft則不太關心C,可能需要更少的更改。


result_of是一個C++ 11元函數(先前在ISO TR1庫標準化從2006)。它是一個模板,它採用可調用類型(例如函數int(void),函數指針int(*)(void),函數類實現operator()或指針到成員函數&T::toCPD)以及該類型的參數類型列表,並提供返回類型如果電話會工作。

要使用帶有指向成員函數的指針的result_of,必須在參數列表中包含父對象類型作爲this的代理。

typedef typename std::result_of< decltype(& T::toCPD) (T *) >::type D; 

這是很脆,但因爲&T::toCPD不能,如果有任何過載,如非const版本解決。儘管必須明確寫出T *T const *!在大多數情況下,你最好用decltypedeclval

+0

沒有特殊的成員函數類型。成員函數的類型是正常的函數類型。例如,成員函數指針是指向正常函數類型的成員指針:'identity :: type A :: *'等價於void(A :: *)()'。您不能將成員指針類型傳遞給'result_of'。特別是,'result_of <> :: type'被指定爲'decltype(declval ()(declval ()...))',其中'Fn'是函數類型/函數對象類型或對其傳遞的引用。 – 2010-05-04 17:06:25

+0

GCC有時會在類「T」中爲類型爲「void()」的函數輸出「type」void(T ::)()或類似的函數。但是這種類型不存在 - 這只是實現細節的冒泡。 – 2010-05-04 17:07:15

+0

實際上,仔細一看,它更像'result_if '。所以,'Fn'不能是一個函數類型(type-id會指定一個函數返回一個函數)。 'Fn'必須是對函數對象的函數或引用或直接類型的引用。和「參數」就是所謂的參數。 – 2010-05-04 17:13:29

3

result_of既不是運算符,也不是函數。的result_of是具有作爲模板參數和對成員類型

typedef typename result_of<T::toCPD()>::type D; 
+0

在模板參數中調用函數永遠不會有效。 – Potatoswatter 2010-05-04 09:58:10

+0

它看起來像decltype應該已經工作。除非OP的編譯器當然不支持 – jalf 2010-05-04 12:05:15

+0

result_of的頭文件是什麼? – Sumant 2010-05-04 15:43:41