Re: Conversion error in template specialization
On 12 Mai, 11:18, "Matthias Hofmann" <hofm...@anvil-soft.com> wrote:
"Daniel Kr?gler" <daniel.krueg...@googlemail.com> schrieb im Newsbeitragnews:1178922795.227672.299810@p77g2000hsh.googlegroups.com...
#include <algorithm>
#include <cstring>
#include <iostream>
namespace std
{
template <> inline
char* const& min( char* const& a,
char* const& b )
{
return const_cast<char* const&>(
min<const char* const>( a, b ) );
}
template <> inline
const char* const& min( const char* const& a,
const char* const& b )
{
return std::strcmp(
a, b ) < 0 ? a : b;
}
}
int main()
{
char* a = "456";
char* b = "123";
std::cout << std::min( a, b ) << std::endl;
return 0;
}
It looks like there's no way to get rid of the const_cast, but in this
case,
it should not lead to undefined behaviour, should it?
It causes undefined behaviour, but for different
reasons than you assume ;-). By specializating std::min
for a non-user-defined type (i.e. for char* and const char*)
you stumble across 17.4.3.1:
"[..] Such a specialization (complete or partial) of a
standard library template results in undefined behavior
unless the declaration depends on a user-defined
name of external linkage and unless the specialization
meets the standard library requirements for the original
template."
But you are correct that the above used const_cast
itself is fine. But it does not what you want ;-)
Note that order matters in this case, because
both min specializations are no longer templates
with "unresolved" parameters. That means, that the
first specialization performs lookup which finds only
the primary template from <algorithm>! This compiles,
because the primary template applies < on the two
given pointers (which is what you wanted to prevent).
There is a third problem as well: Even by refactoring
into another namespace and reordering the overloads
it will invoke the primary template as actual comparator
(that is after entering the char* specialization). The
reason is, that you aquire the specialization for
const char* const. You have not provided one (and
never could do so!). To fix this final issue, you simply
have to remove the last const qualifier in the call:
return const_cast<char* const&>(
min<const char*>( a, b ) );
Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]