11

I'm seeing an error related to templates (compiler is Visual Studio 2012) that I don't understand. Here's the code, boiled down to the essentials:

// Templated class - generic 
template <typename T>
class Test
{
    public:
        void WorksFine() {} // Comiples and works as expected at runtime
        void Problem();     
};

// Templated class - expicit specialization for T = int.
template <>
class Test<int>
{
        public:
            void WorksFine() {} // Comiples and works as expected at runtime
            void Problem();
};

// The definition below compiles and works fine at runtime.
template<typename T> void Test<T>::Problem() {}


// The definition below gives error C2910.
template<> void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

For the WorksFine method, the function definition is inside the explicitly specialized class definition, and everything is fine. But for the Problem method, when I define the method outside the explicitly specialized class definition, I get error C2910

Why is this? Error C2910 indicates that the problem is that Test::Problem() is already defined. But it is not defined inside the class...there is no function definition only a declaration.

It seems pretty lame to be able to do something or not depending on where you choose to put the function definition, which I always though was more of a style/syntax decision, not a functionality/semantics decision. Am I missing something?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
David Stone
  • 1,132
  • 7
  • 18

3 Answers3

9

You don't need the template<>. Just write:

void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

The template<> syntax on a member specialization is required where explicitly instantiating a member on its own; it is omitted when defining a member of an already existing specialization.

template<typename T> struct X { static int i; };
template<> int X<int>::i = 0;  // member instantiation, uses template<>

template<typename T> struct Y { static int i; };
template<> struct Y<int> { static int i; }  // template specialization
int Y<int>::i = 0;  // no template<>
ecatmur
  • 152,476
  • 27
  • 293
  • 366
0

You don't need template anymore in the explicit function definition: void Test<int>::Problem() {printf("In Test::Problem(int instantiation)\n");}

In this case g++ gives a slightly better error message error: template-id 'Problem<>' for 'void Test<int>::Problem()' does not match any template declaration

Mark B
  • 95,107
  • 10
  • 109
  • 188
0

Try this:

// The definition below gives error C2910.
void Test<int>::Problem() 
{
    printf("In Test::Problem(int instantiation)\n");
}

int main()
{
    Test<int> hey; 

    hey.Problem(); 
    return 0;
};
tmaric
  • 5,347
  • 4
  • 42
  • 75