PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > specialization of member template
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
specialization of member template

Réponse
 
LinkBack Outils de la discussion
Vieux 07/02/2008, 16h34   #1
mark.mac@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut specialization of member template

Hello,

I couldn't figure out how to specialize the following member template:

#include <iostream>
template <typename T1> class sample {
T1 value;

public:
sample(T1 v) : value(v) {}
template <typename T2> T1 val(T2 arg);
};

template <typename T1> template <typename T2> T1 sample<T1>::val(T2 arg)
{
return arg + value;
}

template <typename T1> template <> T1 sample<T1>::val(char arg)
{
return arg + value;
}

int main()
{
sample<int> s(0);
char c = 'a';
int i = 10;
std ::cout << s.val(c) << std::endl;
std::cout << s.val(i) << std::endl;
return 0;
}


I only want to partial specialize with T2 = char. Above gives error
"enclosing class templates are not explicitly specialized"

How do I fix this? Thanks.

Mark

  Réponse avec citation
Vieux 07/02/2008, 16h55   #2
pastbin@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

On Feb 7, 5:34 pm, mark....@gmail.com wrote:
> Hello,
>
> I couldn't figure out how to specialize the following member template:
>
> #include <iostream>
> template <typename T1> class sample {
> T1 value;
>
> public:
> sample(T1 v) : value(v) {}
> template <typename T2> T1 val(T2 arg);
>
> };
>
> template <typename T1> template <typename T2> T1 sample<T1>::val(T2 arg)
> {
> return arg + value;
>
> }
>
> template <typename T1> template <> T1 sample<T1>::val(char arg)
> {
> return arg + value;
>
> }
>
> int main()
> {
> sample<int> s(0);
> char c = 'a';
> int i = 10;
> std ::cout << s.val(c) << std::endl;
> std::cout << s.val(i) << std::endl;
> return 0;
>
> }
>
> I only want to partial specialize with T2 = char. Above gives error
> "enclosing class templates are not explicitly specialized"
>
> How do I fix this? Thanks.
>
> Mark


You can't explicitly specialize a class or member template unless its
enclosing class templates are also explicitly specialized.
  Réponse avec citation
Vieux 07/02/2008, 17h06   #3
mark.mac@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

pastbin@gmail.com wrote:
> On Feb 7, 5:34 pm, mark....@gmail.com wrote:
>> Hello,
>>
>> I couldn't figure out how to specialize the following member template:
>>
>> #include <iostream>
>> template <typename T1> class sample {
>> T1 value;
>>
>> public:
>> sample(T1 v) : value(v) {}
>> template <typename T2> T1 val(T2 arg);
>>
>> };
>>
>> template <typename T1> template <typename T2> T1 sample<T1>::val(T2 arg)
>> {
>> return arg + value;
>>
>> }
>>
>> template <typename T1> template <> T1 sample<T1>::val(char arg)
>> {
>> return arg + value;
>>
>> }
>>
>> int main()
>> {
>> sample<int> s(0);
>> char c = 'a';
>> int i = 10;
>> std ::cout << s.val(c) << std::endl;
>> std::cout << s.val(i) << std::endl;
>> return 0;
>>
>> }
>>
>> I only want to partial specialize with T2 = char. Above gives error
>> "enclosing class templates are not explicitly specialized"
>>
>> How do I fix this? Thanks.
>>
>> Mark

>
> You can't explicitly specialize a class or member template unless its
> enclosing class templates are also explicitly specialized.


So are you saying I have to specialized T1 to make it work?
  Réponse avec citation
Vieux 07/02/2008, 17h15   #4
pastbin@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

On Feb 7, 6:06 pm, mark....@gmail.com wrote:
>
> So are you saying I have to specialized T1 to make it work?


Yes. It could be:

template <> template <> int sample<int>::val<char>(char arg)
{
return arg + value;
}
  Réponse avec citation
Vieux 07/02/2008, 17h29   #5
Marek Vondrak
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

>> So are you saying I have to specialized T1 to make it work?

You can implement val() by delegation to an overloaded function or a
function of a er template that takes the two template parameters T1 and
T2 and is partially specialized as appropriate.

-- Marek


  Réponse avec citation
Vieux 07/02/2008, 20h09   #6
Andrey Tarasevich
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

mark.mac@gmail.com wrote:
> ...
> I couldn't figure out how to specialize the following member template:
>
> #include <iostream>
> template <typename T1> class sample {
> T1 value;
>
> public:
> sample(T1 v) : value(v) {}
> template <typename T2> T1 val(T2 arg);
> };
>
> template <typename T1> template <typename T2> T1 sample<T1>::val(T2 arg)
> {
> return arg + value;
> }
>
> template <typename T1> template <> T1 sample<T1>::val(char arg)
> {
> return arg + value;
> }
> ...
> I only want to partial specialize with T2 = char. Above gives error
> "enclosing class templates are not explicitly specialized"
>
> How do I fix this? Thanks.


In C++ for some reason explicit specialization of member templates is
only allowed when the enclosing class template is also explicitly
specialized.

For example, the following code is ill-formed for exactly that reason

template<typename T> struct A {
template<typename U> struct B { int i; };
template<> struct B<int> { int j; }; // <- ERROR
};

With class templates there's an [ugly] workaround: partial
specialization of member templates are perfectly OK, even without
specializing the enclosing class, so the above can be turned into a
partial specialization by introducing a dummy parameter

template<typename T> struct A {
template<typename U, typename DUMMY = void> struct B { int i; };
template<typename DUMMY> struct B<int, DUMMY> { int i; }; // <- OK
};

...
A<void>::B<char> bc;
A<void>::B<int> bi;

bc.i = 4;
bi.j = 2;

It is not exactly the same thing, but it s in many cases (which
makes the aforementioned restriction on explicit specialization look
even more illogical).

In your case though we are dealing with a member function template, not
a member class template. Function templates don't support partial
specialization, which means that we can't use the above workaround.
However, I think you can achieve [almost?] what you want by using a
different C++ mechanism - function overloading. Just supply an
overloaded version of your function with 'char' argument and you should
be OK. Of course, you'll have to add its declaration to the template
class definition

template<typename T1> class sample {
T1 value;

public:
sample(T1 v) : value(v) {}
template<typename T2> T1 val(T2 arg);
T1 val(char arg);
};

template<typename T1> template<typename T2> T1 sample<T1>::val(T2 arg)
{
return arg + value;
}

template<typename T1> T1 sample<T1>::val(char arg)
{
return arg + value;
}

In contexts when member template arguments are not specified, the
compiler will select the overloaded function.

sample<int> s;
s.val('c'); // calls the overloaded 'char' version

But keep in mind that when the template arguments are specified
explicitly (or a mere '<>' is used), the template version will be chosen

s.val<>('c'); // instantiates and calls the template version
s.val<char>('c'); // instantiates and calls the template version

In this respect it is different from explicit specialization. I don't
know whether this matters in your case.

--
Best regards,
Andrey Tarasevich
  Réponse avec citation
Vieux 07/02/2008, 22h56   #7
Andrey Tarasevich
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: [typo fixed] specialization of member template

Andrey Tarasevich wrote:
> ...
> With class templates there's an [ugly] workaround: partial
> specialization of member templates are perfectly OK, even without
> specializing the enclosing class, so the above can be turned into a
> partial specialization by introducing a dummy parameter
>
> template<typename T> struct A {
> template<typename U, typename DUMMY = void> struct B { int i; };
> template<typename DUMMY> struct B<int, DUMMY> { int i; }; // <- OK
> };


Sorry for the typo. Should be

...
template<typename DUMMY> struct B<int, DUMMY> { int j; }; // <- OK
...

--
Best regards,
Andrey Tarasevich
  Réponse avec citation
Vieux 08/02/2008, 09h35   #8
mark.mac@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: specialization of member template

Andrey Tarasevich wrote:
[snip]
>
> In your case though we are dealing with a member function template, not
> a member class template. Function templates don't support partial
> specialization, which means that we can't use the above workaround.
> However, I think you can achieve [almost?] what you want by using a
> different C++ mechanism - function overloading. Just supply an
> overloaded version of your function with 'char' argument and you should
> be OK. Of course, you'll have to add its declaration to the template
> class definition


Yes, that's what I did, thanks for your time.
Mark
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 22h45.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,17425 seconds with 16 queries