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 > Function template specialization
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Function template specialization

Réponse
 
LinkBack Outils de la discussion
Vieux 04/06/2008, 21h55   #1
sheffmail@mail.ru
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Function template specialization

I have the following code:

template <class T>
struct MyS
{
};

template<class T>
inline const T& function(const std::locale& loc)
{
std::cout << "generic" << std::endl;
}

template <class CharType, class Traits, class Allocator>
inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
function< MyS< std::basic_string<CharType, Traits, Allocator> >
>(const std::locale& loc)

{
std::cout << "specialized" << std::endl;
}

int main(int argc, char* argv[])
{
function< MyS<std::string> >(std::locale()); //Should print
"specialized"
function< MyS<std::wstring> >(std::locale()); //Should print
"specialized"
function< MyS<int> >(std::locale()); //Should print "generic"

return 0;
}

Which doesn't compile, I believe it's because you can't partially
specialize function templates. But I really need to
get the desired behavior(Note the "Should print"s in comments), how
can this be done ?
  Réponse avec citation
Vieux 04/06/2008, 22h05   #2
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

sheffmail@mail.ru wrote:
> I have the following code:
>
> template <class T>
> struct MyS
> {
> };
>
> template<class T>
> inline const T& function(const std::locale& loc)
> {
> std::cout << "generic" << std::endl;
> }
>
> template <class CharType, class Traits, class Allocator>
> inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
> function< MyS< std::basic_string<CharType, Traits, Allocator> >
> > (const std::locale& loc)

> {
> std::cout << "specialized" << std::endl;
> }
>
> int main(int argc, char* argv[])
> {
> function< MyS<std::string> >(std::locale()); //Should print
> "specialized"
> function< MyS<std::wstring> >(std::locale()); //Should print
> "specialized"
> function< MyS<int> >(std::locale()); //Should print "generic"
>
> return 0;
> }
>
> Which doesn't compile, I believe it's because you can't partially
> specialize function templates.


Correct.

> But I really need to
> get the desired behavior(Note the "Should print"s in comments), how
> can this be done ?


You can invent your own traits class and specialise that (or *on* that).
Full specialisations of function templates *are* allowed.

BTW, what's the role of 'MyS' template here? It seems superfluous.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
  Réponse avec citation
Vieux 04/06/2008, 22h16   #3
sheffmail@mail.ru
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> sheffm...@mail.ru wrote:
> > I have the following code:

>
> > template <class T>
> > struct MyS
> > {
> > };

>
> > template<class T>
> > inline const T& function(const std::locale& loc)
> > {
> > std::cout << "generic" << std::endl;
> > }

>
> > template <class CharType, class Traits, class Allocator>
> > inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
> > function< MyS< std::basic_string<CharType, Traits, Allocator> >
> > > (const std::locale& loc)

> > {
> > std::cout << "specialized" << std::endl;
> > }

>
> > int main(int argc, char* argv[])
> > {
> > function< MyS<std::string> >(std::locale()); //Should print
> > "specialized"
> > function< MyS<std::wstring> >(std::locale()); //Should print
> > "specialized"
> > function< MyS<int> >(std::locale()); //Should print "generic"

>
> > return 0;
> > }

>
> > Which doesn't compile, I believe it's because you can't partially
> > specialize function templates.

>
> Correct.
>
> > But I really need to

>
> > get the desired behavior(Note the "Should print"s in comments), how
> > can this be done ?

>
> You can invent your own traits class and specialise that (or *on* that).
> Full specialisations of function templates *are* allowed.


Oh, forgot to mention that I need to get this behavior without
changing the signature of generic function:

template<class T>
inline const T& function(const std::locale& loc)

Is it possible ?

>
> BTW, what's the role of 'MyS' template here? It seems superfluous.
>


Yes, in this simple example it's insignificant, though it matters in
context from which this code was taken.

> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask


  Réponse avec citation
Vieux 04/06/2008, 23h22   #4
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

sheffmail@mail.ru wrote:
> On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> sheffm...@mail.ru wrote:
>>> I have the following code:
>>> template <class T>
>>> struct MyS
>>> {
>>> };
>>> template<class T>
>>> inline const T& function(const std::locale& loc)
>>> {
>>> std::cout << "generic" << std::endl;
>>> }
>>> template <class CharType, class Traits, class Allocator>
>>> inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
>>> function< MyS< std::basic_string<CharType, Traits, Allocator> >
>>> > (const std::locale& loc)
>>> {
>>> std::cout << "specialized" << std::endl;
>>> }
>>> int main(int argc, char* argv[])
>>> {
>>> function< MyS<std::string> >(std::locale()); //Should print
>>> "specialized"
>>> function< MyS<std::wstring> >(std::locale()); //Should print
>>> "specialized"
>>> function< MyS<int> >(std::locale()); //Should print "generic"
>>> return 0;
>>> }
>>> Which doesn't compile, I believe it's because you can't partially
>>> specialize function templates.

>> Correct.
>>
>> > But I really need to

>>
>>> get the desired behavior(Note the "Should print"s in comments), how
>>> can this be done ?

>> You can invent your own traits class and specialise that (or *on* that).
>> Full specialisations of function templates *are* allowed.

>
> Oh, forgot to mention that I need to get this behavior without
> changing the signature of generic function:
>
> template<class T>
> inline const T& function(const std::locale& loc)
>
> Is it possible ?


So, you have a function template that you want to behave differently if
you give it some special *set of* Ts, right. And that set is unbounded,
right? If it is, the solution is to wrap those in a class template and
specialise that:

template<class T> struct Caller {
static T& call(const std::locale& loc) {
return function<T>(loc);
}
};

template<class T, class U> struct Caller<MyS<T,U> > {
static MyS<T,U>& call(const std::locale& loc) {
return function<MyS<T,U> >(loc);
}
};

Of course in that case you need to refactor the code that calls the
functions from

function<blah>(loc);

to

Caller<blah>::function(loc);

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
  Réponse avec citation
Vieux 05/06/2008, 00h51   #5
Daniel Pitts
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

Victor Bazarov wrote:
> sheffmail@mail.ru wrote:
>> On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>>> sheffm...@mail.ru wrote:
>>>> I have the following code:
>>>> template <class T>
>>>> struct MyS
>>>> {
>>>> };
>>>> template<class T>
>>>> inline const T& function(const std::locale& loc)
>>>> {
>>>> std::cout << "generic" << std::endl;
>>>> }
>>>> template <class CharType, class Traits, class Allocator>
>>>> inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
>>>> function< MyS< std::basic_string<CharType, Traits, Allocator> >
>>>> > (const std::locale& loc)
>>>> {
>>>> std::cout << "specialized" << std::endl;
>>>> }
>>>> int main(int argc, char* argv[])
>>>> {
>>>> function< MyS<std::string> >(std::locale()); //Should print
>>>> "specialized"
>>>> function< MyS<std::wstring> >(std::locale()); //Should print
>>>> "specialized"
>>>> function< MyS<int> >(std::locale()); //Should print "generic"
>>>> return 0;
>>>> }
>>>> Which doesn't compile, I believe it's because you can't partially
>>>> specialize function templates.
>>> Correct.
>>>
>>> > But I really need to
>>>
>>>> get the desired behavior(Note the "Should print"s in comments), how
>>>> can this be done ?
>>> You can invent your own traits class and specialise that (or *on* that).
>>> Full specialisations of function templates *are* allowed.

>>
>> Oh, forgot to mention that I need to get this behavior without
>> changing the signature of generic function:
>>
>> template<class T>
>> inline const T& function(const std::locale& loc)
>>
>> Is it possible ?

>
> So, you have a function template that you want to behave differently if
> you give it some special *set of* Ts, right. And that set is unbounded,
> right? If it is, the solution is to wrap those in a class template and
> specialise that:
>
> template<class T> struct Caller {
> static T& call(const std::locale& loc) {
> return function<T>(loc);
> }
> };
>
> template<class T, class U> struct Caller<MyS<T,U> > {
> static MyS<T,U>& call(const std::locale& loc) {
> return function<MyS<T,U> >(loc);
> }
> };
>
> Of course in that case you need to refactor the code that calls the
> functions from
>
> function<blah>(loc);
>
> to
>
> Caller<blah>::function(loc);
>
> V

Or replace function<blah> implementation to forward to
Caller<blah>::function until you can refactor.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
  Réponse avec citation
Vieux 05/06/2008, 07h15   #6
sheffmail@mail.ru
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

On Jun 5, 3:51 am, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.net> wrote:
> Victor Bazarov wrote:
> > sheffm...@mail.ru wrote:
> >> On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> >>> sheffm...@mail.ru wrote:
> >>>> I have the following code:
> >>>> template <class T>
> >>>> struct MyS
> >>>> {
> >>>> };
> >>>> template<class T>
> >>>> inline const T& function(const std::locale& loc)
> >>>> {
> >>>> std::cout << "generic" << std::endl;
> >>>> }
> >>>> template <class CharType, class Traits, class Allocator>
> >>>> inline const MyS< std::basic_string<CharType, Traits, Allocator> >&
> >>>> function< MyS< std::basic_string<CharType, Traits, Allocator> >
> >>>> > (const std::locale& loc)
> >>>> {
> >>>> std::cout << "specialized" << std::endl;
> >>>> }
> >>>> int main(int argc, char* argv[])
> >>>> {
> >>>> function< MyS<std::string> >(std::locale()); //Should print
> >>>> "specialized"
> >>>> function< MyS<std::wstring> >(std::locale()); //Should print
> >>>> "specialized"
> >>>> function< MyS<int> >(std::locale()); //Should print "generic"
> >>>> return 0;
> >>>> }
> >>>> Which doesn't compile, I believe it's because you can't partially
> >>>> specialize function templates.
> >>> Correct.

>
> >>> > But I really need to

>
> >>>> get the desired behavior(Note the "Should print"s in comments), how
> >>>> can this be done ?
> >>> You can invent your own traits class and specialise that (or *on* that).
> >>> Full specialisations of function templates *are* allowed.

>
> >> Oh, forgot to mention that I need to get this behavior without
> >> changing the signature of generic function:

>
> >> template<class T>
> >> inline const T& function(const std::locale& loc)

>
> >> Is it possible ?

>
> > So, you have a function template that you want to behave differently if
> > you give it some special *set of* Ts, right. And that set is unbounded,
> > right? If it is, the solution is to wrap those in a class template and
> > specialise that:

>
> > template<class T> struct Caller {
> > static T& call(const std::locale& loc) {
> > return function<T>(loc);
> > }
> > };

>
> > template<class T, class U> struct Caller<MyS<T,U> > {
> > static MyS<T,U>& call(const std::locale& loc) {
> > return function<MyS<T,U> >(loc);
> > }
> > };

>
> > Of course in that case you need to refactor the code that calls the
> > functions from

>
> > function<blah>(loc);

>
> > to

>
> > Caller<blah>::function(loc);

>
> > V

>
> Or replace function<blah> implementation to forward to
> Caller<blah>::function until you can refactor.
>
> --
> Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>


That's the problem, I can't modify declaration nor implementation of
"generic" function, because it's actually std::use_facet from STL and
I need to specialize it for my type, which is std::ctype< MyS<...> >
  Réponse avec citation
Vieux 05/06/2008, 08h18   #7
jason.cipriani@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

On Jun 5, 2:15 am, sheffm...@mail.ru wrote:
> That's the problem, I can't modify declaration nor implementation of
> "generic" function, because it's actually std::use_facet from STL and
> I need to specialize it for my type, which is std::ctype< MyS<...> >


I don't know if this fit's all your requirements but here is the
closest I could get:

=== BEGIN CODE ===

template<class T>
inline const T& function(const std::locale& loc)
{
std::cout << "generic" << std::endl;

}

// this is your implementation of the specialized function; you only
have to
// do it once, at least that's a plus.
template <class T>
inline const MyS<T> & function_mys (const std::locale &) {
std::cout << "specialized" << std::endl;
}

// but you still have to at least have these one-ish liners for each
string
// type; you lose some genericness there.
template <>
inline const MyS<std::string> & function<MyS<std::string> >
(const std::locale &loc) {
return function_mys<std::string>(loc);
}

template <>
inline const MyS<std::wstring> & function<MyS<std::wstring> >
(const std::locale &loc) {
return function_mys<std::wstring>(loc);
}

=== END CODE ===

The idea there is that you explicitly specialize for every
std::basic_string type you'll be using; but you pass everything off to
function_mys so you still only have to maintain one copy of the
specialized code. Still that means you lose the flexibility of passing
*any* basic_string<A,B,C> since you have to explicitly specialize each
of those short functions.

Jason
  Réponse avec citation
Vieux 05/06/2008, 09h25   #8
sheffmail@mail.ru
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Function template specialization

On Jun 5, 11:18 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.com> wrote:
> On Jun 5, 2:15 am, sheffm...@mail.ru wrote:
>
> > That's the problem, I can't modify declaration nor implementation of
> > "generic" function, because it's actually std::use_facet from STL and
> > I need to specialize it for my type, which is std::ctype< MyS<...> >

>
> I don't know if this fit's all your requirements but here is the
> closest I could get:
>
> === BEGIN CODE ===
>
> template<class T>
> inline const T& function(const std::locale& loc)
> {
> std::cout << "generic" << std::endl;
>
> }
>
> // this is your implementation of the specialized function; you only
> have to
> // do it once, at least that's a plus.
> template <class T>
> inline const MyS<T> & function_mys (const std::locale &) {
> std::cout << "specialized" << std::endl;
>
> }
>
> // but you still have to at least have these one-ish liners for each
> string
> // type; you lose some genericness there.
> template <>
> inline const MyS<std::string> & function<MyS<std::string> >
> (const std::locale &loc) {
> return function_mys<std::string>(loc);
>
> }
>
> template <>
> inline const MyS<std::wstring> & function<MyS<std::wstring> >
> (const std::locale &loc) {
> return function_mys<std::wstring>(loc);
>
> }
>
> === END CODE ===
>
> The idea there is that you explicitly specialize for every
> std::basic_string type you'll be using; but you pass everything off to
> function_mys so you still only have to maintain one copy of the
> specialized code. Still that means you lose the flexibility of passing
> *any* basic_string<A,B,C> since you have to explicitly specialize each
> of those short functions.
>
> Jason


Though I lose flexibility, there's probably no better way to solve my
problem, I guess I use this idea.
Thanks a lot!
  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 11h28.


Édité par : vBulletin® version 3.7.2
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
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,25560 seconds with 16 queries