Connecting Tech Pros Worldwide Forums | Help | Site Map

Function template specialization

sheffmail@mail.ru
Guest
 
Posts: n/a
#1: Jun 27 '08
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 ?

Victor Bazarov
Guest
 
Posts: n/a
#2: Jun 27 '08

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
sheffmail@mail.ru
Guest
 
Posts: n/a
#3: Jun 27 '08

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:
return 0;
}
>
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
Victor Bazarov
Guest
 
Posts: n/a
#4: Jun 27 '08

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
Daniel Pitts
Guest
 
Posts: n/a
#5: Jun 27 '08

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/>
sheffmail@mail.ru
Guest
 
Posts: n/a
#6: Jun 27 '08

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:
Quote:
Is it possible ?
>
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:
to
>
Quote:
Caller<blah>::function(loc);
>
Quote:
V
>
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<...
jason.cipriani@gmail.com
Guest
 
Posts: n/a
#7: Jun 27 '08

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
sheffmail@mail.ru
Guest
 
Posts: n/a
#8: Jun 27 '08

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!
Closed Thread