Specializing the 'non-template' member function works as I expect (see
<1> below). In this case the class's type parameter is specialized.
However, I find that in order to specialize the 'template' member
function's type parameter, I must also specialize the class's type
parameter. Why is this the case? (see <2> below.) Why can't I let the
class type parameter vary and specialize the template member function's
type parameter?
//class template with
// non-template member function and template member function
template <typename T>
class Test{
public:
//non-template member function declaration
void max();
//template member function declaration
template <typename U>
void get(U i);
};
//OK
//generic non-template member function definition
template <typename T>
void Test<T>::max() {std::cout << "non-template member function" <<
"\n";}
//OK
// <1> non-template member specialization
template<>
void Test<int>::max() {std::cout << "non-template member function
specialization" << "\n";}
//OK
//generic template member function definition
template <typename T>
template <typename U>
void Test<T>::get(U i) {std::cout << "template member function" <<
"\n";}
//THIS WON'T COMPILE
// <2> template member function specialization
template <typename T> //doesn't like this
template <>
void Test<T>::get<double>(double i) {std::cout << "template member
function specialization" << "\n";}
//BUT THIS WILL COMPILE. WHY NOT THE EXAMPLE ABOVE?
//template member function specialization
template <> //must also specialize the class type parameter. Why?
template <>
void Test<int>::get<double>(double i) {std::cout << "template member
function specialization" << "\n";}
Any help is much appreciated!!
Matthew
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[]
> //THIS WON'T COMPILE
> // <2> template member function specialization
> template <typename T> //doesn't like this
> template <>
> void Test<T>::get<double>(double i) {std::cout << "template member
> function specialization" << "\n";}
>
> //BUT THIS WILL COMPILE. WHY NOT THE EXAMPLE ABOVE?
> //template member function specialization
> template <> //must also specialize the class type parameter. Why?
> template <>
> void Test<int>::get<double>(double i) {std::cout << "template member
> function specialization" << "\n";}
Because that is the only way the current standard allows one to specialize
enclosed templates: you have to fully specialize an enclosing one before
specializing an enclosed one, no matter whether the enclosed template is a
function or a class template.
The two most common workarounds for specializing class templates's member
function templates are:
1) Make a member function template delegate all the work to a non member
function (template):
template<class U>
void do_foo(U); // this function does all the real work
template<class T>
struct enclosing
{
template<class U>
void foo(U u) { do_foo(u); }
};
// and then you can specialize do_foo() in the way you want to
2) Use overloading instead of specializing:
template<class T>
struct enclosing
{
template<class U>
void foo(U u) { this->do_foo(u); }
template<class U>
void do_foo(U u) { /*generic*/ }
void do_foo(int) { /*overload for int*/ }
};
--
Maxim Yegorushkin