Yantao Xie
Yantao Xie

Reputation: 12896

How do I define a template member function outside of a full specialized template class's definition?

The following code can be build successfully.

#include <iostream>
#include <string>
using namespace std;

template <class T>
struct Foo
{
    template <class S>
    void print(const T& t, const S& s);
};

template <>
struct Foo<int>
{
    template <class S>
    void print(const int& t, const S& s)
    {
        cout << s << " " << t << endl;
    }
};

int main(void)
{
    string str("hello");
    Foo<int> foo;
    foo.print(7, str);
    return 0;
}

But if I move the definition of the member function Foo<int>::print(...) outside the definition of the class Foo<int> like below

template <>
template <class S>
void Foo<int>::print(const int& t, const S& s)
{
    cout << s << " " << t << endl;
}

I got a GCC compiling error like this:

error: too many template-parameter-lists
 void Foo<int>::print(const int& t, const S& s)
      ^

Where did I make a mistake?

Upvotes: 1

Views: 2507

Answers (1)

T.C.
T.C.

Reputation: 137315

§14.7.3 [temp.expl.spec]/p5:

Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax. The same is true when defining a member of an explicitly specialized member class. However, template<> is used in defining a member of an explicitly specialized member class template that is specialized as a class template.

print is not a class template. Hence, remove the template <>:

template <>
struct Foo<int>
{
    template <class S>
    void print(const int& t, const S& s);
};

template <class S>
void Foo<int>::print(const int& t, const S& s)
{
    cout << s << " " << t << endl;
}

Demo.


Note that if you do not explicitly specialize Foo<int>, but tries to define Foo<int>::print directly, then you are explicitly specializing a member of a particular implicit instantiation of Foo, and not defining a member of an explicit specialization. For that, you need template <>:

template <class T>
struct Foo
{
    template <class S>
    void print(const T& t, const S& s);
};

template <>
template <class S>
void Foo<int>::print(const int& t, const S& s)
{
    cout << s << " " << t << endl;
}

Upvotes: 4

Related Questions