Say I have a templated class like
template struct Node
{
// general method split
void split()
{
// ... actual code her
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.
Awkward method that I usually use: Declare a "basic" template implementation. Then declare your template implementation, the default implementation would just inherit the "basic" one. The customize would inherit the "basic", plus override specific methods. Like this:
template <typename T> struct NodeBase
{
// methods
};
template <typename T> struct Node
:public NodeBase<T>
{
// nothing is changed
};
template <> struct Node<SpecificType>
:public NodeBase<SpecificType>
{
// re-define methods you want
};
Note that the "method overriding" has nothing to do with virtual functions or etc. It's just a declaring a function with the same name and parameters as in the base - the compiler will automatically use 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.
Just define some
template<>
void Node<Triangle*>::split()
{
}
after the primary template, but before the first time you ever instantiate it.