K.W.
K.W.

Reputation: 59

Specialisation of member function templates in c++

I want to create a generic class containing a method displaying one message if the type of the class is int and the other when it's double. Here's my code:

template<class T>
class A {
public:
    template <T> void B();

};

template<class T>
void A<int>::B{
//some code here
}

template<class T>
void A<double>::B{
//some code here
}

I got the following errors:

'double': illegal type for non-type template parameter '__formal'

'A<int>::B': unable to match function definition to an existing declaration

Thanks in advance for any solutions.

Upvotes: 0

Views: 49

Answers (1)

AndyG
AndyG

Reputation: 41092

A couple of things:

  • There's no reason for B to be a template. You want to specialize for A
  • B is a method. Methods accept parameters. When defining the method, you omitted the parenthesis ()
  • Template specialization always involves an empty template parameter <>

Code:

template<class T>
class A {
public:
    void B();
};

template<>
void A<int>::B(){
   std::cout << "A<int>::B" << std::endl;
}

template<>
void A<double>::B(){
   std::cout << "A<double>::B" << std::endl;
}

Demo

If you feel compelled to make B a template, I should note that in general one does not perform template specialization on functions. This is primarily because they cannot be partially specialized, and it's almost always better to write an overload. In your case, B takes no arguments, so there's some argument to be made in favor of specialization.

More often than not, one would use a tag dispatching approach instead, coupled with a helper function so that they can choose their desired function by taking advantage of overloading instead. Here's a simple example of tag dispatching for your case:

template<class T>
class A {
public:
    template<class U>
    void B()
    {
        B(ATag<U>{});
    }

    private:
    template<class U>
    struct ATag{};

    void B(ATag<int>)
    {
        std::cout << "B<int>" << std::endl;
    }

    void B(ATag<double>)
    {
        std::cout << "B<double>" << std::endl;
    }
};

tag dispatch demo

Upvotes: 2

Related Questions