|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 ? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
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/> |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
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<...> > |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
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! |
|
![]() |
| Outils de la discussion | |
|
|