Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Class Template Specializations

276 views
Skip to first unread message

Matthew Schaefer

unread,
Jan 30, 2005, 6:53:58 PM1/30/05
to
Below I have set up an example of the following for a template class:
1) a template specialization of a 'non-template' member function, and
2) a template specialization of a 'template' member function. Examples
of both are given below. My question is this:

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! ]

Maxim Yegorushkin

unread,
Jan 31, 2005, 6:43:28 AM1/31/05
to
On 30 Jan 2005 18:53:58 -0500, Matthew Schaefer
<matthewp...@yahoo.com> wrote:

[]

> //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

0 new messages