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 Quote:
>(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 ? | | | | re: Function template specialization sheffmail@mail.ru wrote: Quote:
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 Quote:
(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. Quote:
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 | | | | re: Function template specialization
On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.netwrote: Quote:
sheffm...@mail.ru wrote: Quote:
I have the following code:
> Quote:
template <class T>
struct MyS
{
};
> Quote:
template<class T>
inline const T& function(const std::locale& loc)
{
std::cout << "generic" << std::endl;
}
> Quote:
template <class CharType, class Traits, class Allocator>
inline const MyS< std::basic_string<CharType, Traits, Allocator&
function< MyS< std::basic_string<CharType, Traits, Allocator Quote:
(const std::locale& loc)
{
std::cout << "specialized" << std::endl;
}
> Quote:
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"
> > Quote:
Which doesn't compile, I believe it's because you can't partially
specialize function templates.
>
Correct.
> Quote:
But I really need to
> Quote:
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 ? Quote:
>
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. Quote:
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
| | | | re: Function template specialization sheffmail@mail.ru wrote: Quote:
On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.netwrote: Quote:
>sheffm...@mail.ru wrote: Quote:
>>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.
>> Quote:
> But I really need to
>> Quote:
>>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 Tstruct Caller {
static T& call(const std::locale& loc) {
return function<T>(loc);
}
};
template<class T, class Ustruct 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 | | | | re: Function template specialization
Victor Bazarov wrote: Quote: sheffmail@mail.ru wrote: Quote:
>On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.netwrote: Quote:
>>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 Tstruct Caller {
static T& call(const std::locale& loc) {
return function<T>(loc);
}
};
>
template<class T, class Ustruct 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<blahimplementation to forward to
Caller<blah>::function until you can refactor.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/> | | | | re: Function template specialization
On Jun 5, 3:51 am, Daniel Pitts
<newsgroup.spamfil...@virtualinfinity.netwrote: Quote:
Victor Bazarov wrote: Quote:
sheffm...@mail.ru wrote: Quote:
On Jun 5, 1:05 am, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>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.
> Quote: Quote:
> But I really need to
> Quote: Quote:
>>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.
> Quote: Quote:
Oh, forgot to mention that I need to get this behavior without
changing the signature of generic function:
> Quote: Quote:
template<class T>
inline const T& function(const std::locale& loc)
> > Quote:
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:
> Quote:
template<class Tstruct Caller {
static T& call(const std::locale& loc) {
return function<T>(loc);
}
};
> Quote:
template<class T, class Ustruct Caller<MyS<T,U {
static MyS<T,U>& call(const std::locale& loc) {
return function<MyS<T,U(loc);
}
};
> Quote:
Of course in that case you need to refactor the code that calls the
functions from
> Quote:
function<blah>(loc);
> > Quote:
Caller<blah>::function(loc);
> >
Or replace function<blahimplementation 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<... | | | | re: Function template specialization
On Jun 5, 2:15 am, sheffm...@mail.ru wrote: Quote:
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,Csince you have to explicitly specialize each
of those short functions.
Jason | | | | re: Function template specialization
On Jun 5, 11:18 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.comwrote: Quote:
On Jun 5, 2:15 am, sheffm...@mail.ru wrote:
> Quote:
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,Csince 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! |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,510 network members.
|