2011-04-07 181 views
35

我有一些我無法修改的類。每個都有一個拷貝構造函數,至少有一個其他的構造函數,以及一個返回某個值的函數foo()。我想創建一個可以從每個類派生出來的類模板,並且有一個與返回類型foo()相同類型的數據成員(對不起,如果我有一些術語錯誤)。獲取沒有對象的成員函數的返回類型

換句話說,我想一個類模板

template<typename T> class C : public T 
{ 
    footype fooresult; 
}; 

其中footypeT::foo()返回類型。

如果基類都有,也就是說,一個默認的構造函數,我可以做

decltype(T().foo()) fooresult; 

(與海灣合作委員會的C++ 0x的功能),但類不具有任何公共構造特別,除了複製構造函數。

GCC也不允許decltype(this->foo()),雖然顯然有可能這將被添加到C++ 0x標準 - 有誰知道這有多可能嗎?

我覺得應該可以做沿着decltype(foo())decltype(T::foo()),但這些線的東西似乎不工作:GCC給出了形式cannot call member function 'int A::foo()' without object的錯誤。

當然,我可以有一個額外的模板參數footype,或者甚至是類型爲T的非類參數,但有什麼辦法可以避免這種情況嗎?

+0

有人可能會想出更優雅的東西,但'typename decltype(mem_fun(&T :: foo())):: result_type'或者類似的東西呢? – 2011-04-07 11:33:44

+0

@Steve:這個名字'return_type'來自哪裏? – Nawaz 2011-04-07 11:36:31

+0

@Nawaz:我的想象力。命中刷新;-) – 2011-04-07 11:38:57

回答

55

你不需要這樣 - 請記住,因爲decltype不評估它的參數,所以你可以致電nullptr

decltype(((T*)nullptr)->foo()) footype; 
29

另一個替代方案是:

#include <utility> 

template<typename T> class C : public T 
{ 
    decltype(std::declval<T>().foo()) footype; 
}; 

declval返回T&&。或者,如果FOO可能與右值-REF預選賽超載,你要確保你得到foo的左值過載:

decltype(std::declval<T&>().foo()) footype; 

在這個例子中declval返回T&

((T*)nullptr)->類似,std::declvalT型號沒有要求。

+1

要迂腐'std :: declval'在,而不是,根據FDIS 20.2 [utility]/2 – Cubbi 2011-08-29 17:44:40

+0

好抓!我改變了答案中的標題。謝謝! – 2011-08-29 19:53:55

相關問題