Google Grupper har inte längre stöd för nya Usenet-inlägg eller -prenumerationer. Historiskt innehåll förblir synligt.
Dismiss

Class Template Specializations

276 visningar
Hoppa till det första olästa meddelandet

Matthew Schaefer

oläst,
30 jan. 2005 18:53:582005-01-30
till
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

oläst,
31 jan. 2005 06:43:282005-01-31
till
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 nya meddelanden