 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
YUY0x7 Guest
|
Posted: Sun Jul 31, 2005 1:28 am Post subject: Template specialization of an operator |
|
|
Hi, I am having a bit of trouble with a specialization of operator<<.
Here goes:
class MyStream
{
};
template
MyStream& operator<<(MyStream& lhs, T const &)
{
cout << "operator<< T" << endl;
return lhs;
}
// specialize to work differently for std::string
template <> MyStream& operator<<(MyStream& lhs, string const &)
{
cout << "operator<< const string&" << endl;
return lhs;
}
// specialize to work differently for char const*
template <> MyStream& operator<<(MyStream& lhs, char const * const &)
{
cout << "operator<< char const*" << endl;
return lhs;
}
int main()
{
MyStream strm;
int i = 19;
string mystr = "hello";
strm << "hi" << i << mystr << "n";
return 0;
}
This outputs:
operator<< T
operator<< T
operator<< const string&
operator<< T
Why doesn't strm << "hi" (and << "n") use the specialized version?
Now I tried changing the operator to these:
template
MyStream& operator<<(MyStream& lhs, T)
{
cout << "operator<< T" << endl;
return lhs;
}
// specialize to work differently for std::string
template <> MyStream& operator<<(MyStream& lhs, string const &)
{
cout << "operator<< const string&" << endl;
return lhs;
}
// specialize to work differently for char const*
template <> MyStream& operator<<(MyStream& lhs, char const *)
{
cout << "operator<< char const*" << endl;
return lhs;
}
And the output is:
operator<< char const*
operator<< char const*
operator<< T
operator<< char const*
Now why doesn't strm << mystr use the specialized one? It looks like
it's a perfect match for mystr (and not even using a specialization for
string& works).
Can anyone tell me why this happens, and if there is a way to make this
work for both char const* and string const& ?
Thanks a lot,
George Faraj
[ 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
|
Posted: Sun Jul 31, 2005 11:53 am Post subject: Re: Template specialization of an operator |
|
|
"YUY0x7" <gfaraj (AT) gmail (DOT) com> writes:
| Quote: | class MyStream
{
};
template <typename T
MyStream& operator<<(MyStream& lhs, T const &)
{
cout << "operator<< T" << endl;
return lhs;
}
// specialize to work differently for std::string
template <> MyStream& operator<<(MyStream& lhs, string const &)
{
cout << "operator<< const string&" << endl;
return lhs;
}
// specialize to work differently for char const*
template <> MyStream& operator<<(MyStream& lhs, char const * const &)
{
cout << "operator<< char const*" << endl;
return lhs;
}
int main()
{
MyStream strm;
int i = 19;
string mystr = "hello";
strm << "hi" << i << mystr << "n";
return 0;
}
This outputs:
operator<< T
operator<< T
operator<< const string&
operator<< T
Why doesn't strm << "hi" (and << "n") use the specialized version?
|
Because the specialization for T==const char[3] generated from the
primary template is a perfect match, whereas using the specialization
for char const * const & would require a conversion.
Do you really need specialization? If you can do with overloading:
// overload to work differently for std::std::string
MyStream& operator<<(MyStream& lhs, std::string const &)
{
std::cout << "operator<< const std::string&" << std::endl;
return lhs;
}
// overload to work differently for char const*
MyStream& operator<<(MyStream& lhs, char const *)
{
std::cout << "operator<< char const*" << std::endl;
return lhs;
}
, the behavior will be what you expected in the first place.
| Quote: | Now I tried changing the operator to these:
template
MyStream& operator<<(MyStream& lhs, T)
{
cout << "operator<< T" << endl;
return lhs;
}
// specialize to work differently for std::string
template <> MyStream& operator<<(MyStream& lhs, string const &)
{
cout << "operator<< const string&" << endl;
return lhs;
}
// specialize to work differently for char const*
template <> MyStream& operator<<(MyStream& lhs, char const *)
{
cout << "operator<< char const*" << endl;
return lhs;
}
And the output is:
operator<< char const*
operator<< char const*
operator<< T
operator<< char const*
|
Are you sure? I get
operator<< char const*
operator<< T
operator<< T
operator<< char const*
If strm << i invokes the char const * version, your compiler has a
problem.
| Quote: | Now why doesn't strm << mystr use the specialized one? It looks like
it's a perfect match for mystr (and not even using a specialization
for string& works).
|
It's not a perfect match; the argument's type is std::string, whereas
the parameter type is std::string const &. If you change the parameter
type to std::string, the specialization will be selected; otherwise,
the specialization generated from the primary template is a better
match.
| Quote: | Can anyone tell me why this happens, and if there is a way to make
this work for both char const* and string const& ?
|
As mentioned above, consider using overloading instead of
specialization.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
YUY0x7 Guest
|
Posted: Mon Aug 01, 2005 10:27 am Post subject: Re: Template specialization of an operator |
|
|
Got it, thanks.
Yeah, the output sample I gave was incorrect, it was what you said.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|