If I want to specialise just one method in a template, how do I do it?

You can provide a specialization for only that function outside the class declaration.

template <typename T> struct Node
{
    // general method split
    void split()
    {
        // implementation here or somewhere else in header
    }
};

// prototype of function declared in cpp void splitIntNode( Node & node );

template <>
void Node<int>::split()
{
     splitIntNode( this ); // which can be implemented
}

int main(int argc, char* argv[])
{
   Node <char> x;
   x.split(); //will call original method
   Node <int> k;
   k.split(); //will call the method for the int version
}

If splitIntNode needs access to private members, you can just pass those members into the function rather than the whole Node.


Your case is a fortunate example because you are fully-specializing the template. In other words there is only one template argument, and for the function you wish to specialize, you are providing a fully-specialized instantiation of that function definition. Unfortunately for partial class template specialization, it is a requirement that you re-implement the class.

For example, this works:

template<typename T, typename U>
struct Node
{
    void function() { cout << "Non-specialized version" << endl; }
};

template<>
void Node<int, char>::function() { cout << "Specialized version" << endl; }

The partially specialized version though will not work:

template<typename T, typename U>
struct Node
{
    void function() { cout << "Non-specialized version" << endl; }
};

template<typename U>
void Node<int, U>::function() { cout << "Specialized version" << endl; }

What you may want to-do if you find yourself in the second scenario, in order to avoid the needless duplication of code, is pack all the common elements into a common base-class, and then place all the elements that will be varying with the partial specialization in a derived class. That way you do not need to reduplicate all the common code in the base-class, you would only need to re-write the definitions for the specialized derived class.


Just define some

template<>
void Node<Triangle*>::split()
{
}

after the primary template, but before the first time you ever instantiate it.