Search code examples
c++templatesexplicit-specialization

How to provide a explicit specialization to only one method in a C++ template class?


I have a template class that looks something like this:

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

    // Other stuff
};

template<class T> void C<T>::A() { /* something */ }
template<class T> void C<T>::B() { /* something */ }

What I want is to provide an explicit specialization for only A while retaining the default for B and the "other stuff".

What I have tried so far is

class D { };
template<> void C<D>::A() { /*...*/ } // Gives a link error: multiple definition

Every other variant I've attempted fails with parse errors.


What I did:

The original problem was that the explicit specialization was in a header file so it was getting dumped into several object files and messing up the link (Why doesn't the linker notice all the instances of the symbol are the same a just shut up?)

The solution ends up being to move the explicit specialization from the header file to a code file. However to make the other users of the header file not instance the default version, I needed to place a prototype back in the header. Then to get GCC to actually generate the explicit specialization, I needed to place a dummy variable of the correct type in the code file.


Solution

  • Alternatively to Martin York's inline solution you could also do in your header file:

    class D { };
    template<> void C<D>::A(); // Don't implement here!
    

    And supply a .cpp file with the implementation:

    template<> void C<D>::A() { /* do code here */ }
    

    So you avoid the multiple definitions by supplying a single one. This is also good to hide implementations for specific Types away from the template header file when publishing the library.