如何将C++模板方法的返回类型声明为其他类中的静态方法

How to declare return type of C++ template method to be that of static method in other class?

本文关键字:其他 静态方法 声明 返回类型 C++ 模板方法      更新时间:2023-10-16

我想做有效的C++11等效于以下(明显(无效的代码:

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

我想做的事情可能吗?如果是,如何?

我不认为std::result_of是这样工作的。它被定义为result_of<F(ArgTypes...)>(请参阅cpprreference(。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);
}

另请注意Chris指出的typename

auto应该会成功:

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

在C++14中,您可以跳过decltype:

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

这很有效(http://ideone.com/6pczX3):

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

起初,我认为您可能只需要适当地添加typename,但这并没有奏效。

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

应该是

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

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

(定义相同(。

演示