C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Can I specialize a template for std::pair parameter?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Matt Young
Guest





PostPosted: Thu Jul 07, 2005 2:40 pm    Post subject: Can I specialize a template for std::pair parameter? Reply with quote



If I have a template function with one template parameter, is there a
way to specialize or overload it to handle the case where that
parameter is a std::pair?

For example, suppose I have the following function:

template<typename Entry>
void WriteEntry(Entry const & entry) {
std::cout << "[" << entry << "]";
}

I would like to write a version that takes a std::pair as its
parameter. (The caller is itself a templated function that iterates
over a std::set or a std::map to write out all its entries in a
specified number of columns.) However, if I naively write:

template void WriteEntry(std::pair<Left, Right> const & entry) {
std::cout << "[" << entry.first << ", " << entry.second << "]";
}

then the compiler complains that neither of the two overloads has the
best conversion.

Is there a way to get this to work, or should I be taking a different
approach altogether? (I can think of a few run-time ways of solving
the problem, but it would be more elegant to deduce which output
function to call at compile time.)


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Antoun Kanawati
Guest





PostPosted: Fri Jul 08, 2005 12:42 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote



Matt Young wrote:
Quote:
For example, suppose I have the following function:

template<typename Entry
void WriteEntry(Entry const & entry) {
std::cout << "[" << entry << "]";
}

I would like to write a version that takes a std::pair as its
parameter. (The caller is itself a templated function that iterates
over a std::set or a std::map to write out all its entries in a
specified number of columns.) However, if I naively write:

template void WriteEntry(std::pair std::cout << "[" << entry.first << ", " << entry.second << "]";
}

then the compiler complains that neither of the two overloads has the
best conversion.

Is there a way to get this to work, or should I be taking a different
approach altogether? (I can think of a few run-time ways of solving
the problem, but it would be more elegant to deduce which output
function to call at compile time.)

I just used your code with

int main()
{
WriteEntry(42);
WriteEntry(std::pair
return 0;
}

my compilers did not complain or warn. g++ 3.4.2 and 4.0.0, -Wall.

--
A. Kanawati
[email]NO.antounk.SPAM (AT) comcast (DOT) net[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Kodt
Guest





PostPosted: Fri Jul 08, 2005 1:00 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote



This is an overload, not specialization. One cannot specialize function
templates, this is prohibited by the Holy Standard :)

I examined following code:
#include <iostream>
#include <utility>
#include <typeinfo>

template<class T> char* foo(const T& t)
{
std::cout << "generic foo of " << typeid(t).name() << "n";
return "x";
}
template {
std::cout << "specific foo of " << typeid(t).name() << "n";
return 0;
}
int main()
{
char *x = foo(123); // generic
int y = foo(std::make_pair(1,2)); // specific
}

Comeau 4.3.3 online ( www.comeaucomputing.com/tryitout |
www.nixie.narod.ru/comeau ) compiled this,
while VC 6 sp6 failed, reporting "ambiguous call, none of overloads,
etc."

So, this is a problem of the compiler you use.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Kodt
Guest





PostPosted: Fri Jul 08, 2005 1:02 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote

If you are allowed to change a signature of your template, here is a
way to solve it:

template<class T>
void foo(T t, char dummy) // a prototype uses 'char'
{
cout << "base: " << typeid(t).name();
}

template void foo(pair<T,U> t, int dummy) // all quazy-specializations shall use
'int'
{
cout << "pair: " << typeid(t).name();
}

template void foo(T t)
{
foo(t,0); // specialization is preferred because it doesn't require
additional type conversion (int->char)
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Maeder
Guest





PostPosted: Fri Jul 08, 2005 1:10 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote

"Matt Young" <palaso (AT) gmail (DOT) com> writes:

Quote:
If I have a template function with one template parameter, is there
a way to specialize or overload it to handle the case where that
parameter is a std::pair?

Yes. Not directly though.


Quote:
For example, suppose I have the following function:

template<typename Entry
void WriteEntry(Entry const & entry) {
std::cout << "[" << entry << "]";
}

I would like to write a version that takes a std::pair as its
parameter. (The caller is itself a templated function that iterates
over a std::set or a std::map to write out all its entries in a
specified number of columns.) However, if I naively write:

template void WriteEntry(std::pair std::cout << "[" << entry.first << ", " << entry.second << "]";
}

then the compiler complains that neither of the two overloads has
the best conversion.

This is overloading, not specialization (just for the record; I assume
you know that).


Quote:
Is there a way to get this to work, or should I be taking a different
approach altogether? (I can think of a few run-time ways of solving
the problem, but it would be more elegant to deduce which output
function to call at compile time.)

Delegate to a static member function of a template, which you can
partially specialize. E.g.:

template struct EntryWriter
{
static void write(T const &entry)
{
std::cout << "[" << entry << "]";
}
};

template struct EntryWriter< std::pair
{
static void write(std::pair<T1,T2> const &entry)
{
std::cout << "[" << entry.first << ", " << entry.second << "]";
}
};

template void WriteEntry(T const &entry) {
EntryWriter<T>::write(entry);
}

int main()
{
WriteEntry(6);
WriteEntry(std::make_pair(7,Cool);
}

Since we have specialization here, EntryWriter< std::pair
will be preferred if T is a specialization of std::pair.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ben Hutchings
Guest





PostPosted: Fri Jul 08, 2005 1:15 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote

Matt Young <palaso (AT) gmail (DOT) com> wrote:
Quote:
If I have a template function with one template parameter, is there a
way to specialize or overload it to handle the case where that
parameter is a std::pair?

You can't specialise for std::pair - that would be a partial
specialisation, and those don't exist for function templates.
You can overload, though.

Quote:
For example, suppose I have the following function:

template<typename Entry
void WriteEntry(Entry const & entry) {
std::cout << "[" << entry << "]";
}

I would like to write a version that takes a std::pair as its
parameter. (The caller is itself a templated function that iterates
over a std::set or a std::map to write out all its entries in a
specified number of columns.) However, if I naively write:

template void WriteEntry(std::pair std::cout << "[" << entry.first << ", " << entry.second << "]";
}

then the compiler complains that neither of the two overloads has the
best conversion.
snip


I think your compiler is in error. The code you've posted compiles
without error in VC++ 7.1, Comeau C++ 4.3.3 beta, g++ 3.3 and 3.4.

Ben.

--
Ben Hutchings
Having problems with C++ templates? Your questions may be answered by

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Kodt
Guest





PostPosted: Fri Jul 08, 2005 10:32 am    Post subject: Re: Can I specialize a template for std::pair parameter? Reply with quote

VC6 (I believe Matt Young uses it) doesn't support partial
specialization.
Good compilers have no problems with both overloading of function
templates and partial specialization of class templates.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.