Search code examples
c++templatesconstructorvirtual

Template specialization implementation in cpp file causes template-id does not match error


Consider the following code:

class Bar;

enum Values
{
  ValA,
  ValB, // ...
};

template< typename T >
struct Foo : virtual public Bar
{
};

template<>
struct Foo< ValA >
{
  void doSomething();
};

If I define the implementation of doSomething() in the header file, the program doesn't complain when I use Foo::doSomething(). However, if I move the implementation to a cpp file, as follows, I get an error:

template<>
void Foo< ValA >::doSomething()
{
  // ...
}

The error:

error: template-id 'doSomething<>' for 'void Foo<(Values)0u>::doSomething()' does not match any template declaration.

I'm not sure why this is failing. Moving the specialized implementation to a cpp file should not be a problem, I believe. I've done this before.


Solution

  • There are couple of problems.

    One was pointed out by @dyp in the comments section to your question. You need to use:

    void Foo< ValA >::doSomething()
    {
    }
    

    instead of

    template<>
    void Foo< ValA >::doSomething()
    {
    }
    

    The other one is that you have to change the class template to:

    template< int T >
    struct Foo : virtual public Bar
    {
    };
    

    You can't create a specialization of Foo using ValA, if you use typename as template parameter.