user1196549
user1196549

Reputation:

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.)

Upvotes: 2

Views: 1471

Answers (2)

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.

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.

Upvotes: 5

cppBeginner
cppBeginner

Reputation: 1212

Here is another workaround using 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.

Upvotes: 1

Related Questions