2016-10-13 54 views
2

我想做的有效C++ 11當量以下的(顯然)無效代碼:如何將C++模板方法的返回類型聲明爲其他類中靜態方法的返回類型?

class StaticMethodClass { 
public: 
    static int staticMethod(int a) {return 0;} 
}; 

#include <type_traits> 

template<class T> class ClassTemplate { 
public: 
    decltype(T::staticMethod(int)) methodTemplate(int a); 
}; 

template<class T> 
decltype(T::staticMethod(int)) ClassTemplate<T>::methodTemplate(int a) { 
    return T::staticMethod(a); 
} 

template class ClassTemplate<StaticMethodClass>; 

我從我的編譯器以下錯誤:

/tmp$ g++ -std=c++11 -c a.cpp 
a.cpp:14:26: error: expected primary-expression before ‘int’ 
decltype(T::staticMethod(int)) ClassTemplate<T>::methodTemplate(int a) { 
         ^
a.cpp:14:32: error: prototype for ‘decltype (T:: staticMethod(<expression error>)) ClassTemplate<T>::methodTemplate(int)’ does not match any in class ‘ClassTemplate<T>’ 
decltype(T::staticMethod(int)) ClassTemplate<T>::methodTemplate(int a) { 
           ^
a.cpp:10:36: error: candidate is: int ClassTemplate<T>::methodTemplate(int) 
    decltype(T::staticMethod(int)) methodTemplate(int a); 
            ^
/tmp$ g++ -dumpversion 
4.8.3 

是什麼,我想有可能嗎?如果是這樣,怎麼樣?

回答

2

我不認爲std::result_of以這種方式工作。它的定義爲result_of<F(ArgTypes...)>(見cppreference)。 F參數應該是類型。當你寫T::staticMethod你給result_of函數,而不是類型

F必須是可調用類型,對函數的引用或對可調用類型的引用。用ArgTypes調用F ...必須是一個格式良好的表達式。

所以你想要的是給result_of該函數的引用類型。指向該函數的指針由&T::staticMethod給出,其類型由decltype(&T::staticMethod)給出。此代碼有效。

typename std::result_of<decltype(&T::staticMethod)(int)>::type methodTemplate(int i) { 
    return T::staticMethod(i); 
} 

還要注意typenameChris指出。

0

此作品(http://ideone.com/6pczX3):

decltype(T::staticMethod(int)) methodTemplate(int i) { 
    return T::staticMethod(i); 
} 

起初我還以爲你可能只需要適當地添加typename,但沒有奏效。

+0

,對於初始代碼,其中'methodTemplate()'在類的聲明中實現合作。然而,將該實現移到課程外面會導致同樣的問題。請參閱修訂後的代碼。 –

2

auto應使絕招:

auto methodTemplate(int i) -> decltype(T::staticMethod(i)) { 
    return T::staticMethod(i); 
} 

在C++ 14,你可以跳過decltype

auto methodTemplate(int i) { 
    return T::staticMethod(i); 
} 
+0

@SteveEmmerson嘗試'decltype'。 – AlexD

0
decltype(T::staticMethod(int)) methodTemplate(int a); 

應該

decltype(T::staticMethod(0)) methodTemplate(int a); 

decltype(T::staticMethod(std::declval<int>())) methodTemplate(int a); 

(和相同的定義)。

Demo

相關問題