简体   繁体   English

具有替代返回类型的模板专业化

[英]Template specialization with alternative return type

I have a class template member function and I need to create a specialization that differs by the return type. 我有一个类模板成员函数,我需要创建一个特殊化,该特殊化取决于返回类型。 But this is not allowed. 但这是不允许的。

template<typename Type>
class Class {
    Type Method(Type Argument) {...}
};

template <>
double Class<int>::Method(int Argument) {...}

Can you suggest a workaround ? 您可以提出解决方法吗? (With the goal of hiding the templated definition for int .) (目的是隐藏int的模板定义。)

Let's discuss the root of the problem. 让我们讨论问题的根源。 When you specialize a member function for a class template, it causes the declaration of the class to be instantiated. 当您为类模板专门化成员函数时,它将导致实例化类的声明。 So your specialized out-of-class definition conflicts with the generated declaration. 因此,您的特殊类外定义与生成的声明冲突。

A possible solution would be to add a layer of indirection. 一种可能的解决方案是添加一个间接层。 Don't hard-code the return type as is, but make it depend indirectly on the template parameter, say from a traits class. 不要按原样对返回类型进行硬编码,而是使其间接依赖于模板参数,例如来自traits类。

Something like this: 像这样:

template<typename T>
struct ClassMethodReturn { typedef T type; };

template<>
struct ClassMethodReturn<int> { typedef double type; };

template<typename Type>
class Class {
    typedef typename ClassMethodReturn<Type>::type ret_type;
    ret_type Method(Type Argument) { return ret_type(); }
};

template <>
double Class<int>::Method(int Argument) { return 0.0; }

Thus you control the return type for each specialization rather easily. 因此,您可以轻松控制每个专业化的返回类型。

Here is another workaround using std::enable_if . 这是使用std::enable_if另一种解决方法。

template<typename Type>
class Class {
    public: 
    template <typename TypeDat=Type> std::enable_if_t<std::is_same<TypeDat,int>::value,double> Method(Type Argument) {
        std::cout<<"case 1"<<std::endl;    
    }
    template <typename TypeDat=Type> std::enable_if_t<!std::is_same<TypeDat,int>::value,Type> Method(Type Argument) {
        std::cout<<"case 2"<<std::endl;
    }

};
int main() {
    Class<int> a;
    a.Method(5);   //print case 1
    Class<char> b;
    b.Method('c'); //print case 2
}

Demo 演示

Personally, I love StoryTeller's solution. 就个人而言,我喜欢StoryTeller的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM