Re: ambiguous overload when used with derived classes?
On May 23, 2:01 pm, James Kanze <james.ka...@gmail.com> wrote:
On 23 mai, 06:29, sebastian <sebastianga...@gmail.com> wrote:
[code]
struct foo
{ };
void
bar( foo const & lhs, foo const & rhs )
{ }
template < typename Lhs >
void
bar( Lhs const & lhs, foo const & rhs )
{ }
template < typename Rhs >
void
bar( foo const & lhs, Rhs const & rhs )
{ }
struct baz : foo
{ };
int
main( void )
{
bar( baz( ), baz( ) ); // error: ambiguous overload
}
[/code]
I thought that the compiler would deduce bar( foo const &, foo
const & ).
Why? The compiler has to choose between three functions:
void bar( foo const&, foo const& ) ;
void bar( baz cosnt&, foo const& ) ;
void bar( foo const&, baz const& ) ;
Note the second and third bar() functins are actually function
template "specializations", so it would be more accurate to present
the three bar() candidate functions as:
void bar( foo const&, foo const& ) ;
template <>
void bar<baz>( baz cosnt&, foo const& ) ;
template <>
void bar<baz>( foo const&, baz const& ) ;
For the first argument, the second function is the best match,
and for the second, the last function. How can the compiler
decide?
Presumably in the same way that the C++ compiler would choose the best
bar() overload - if there were only the first bar() functions from
which to choose. In other words, once the third bar() function is
eliminated, the call to bar() is no longer ambiguous. There is no
ambiguity because - when the compiler has to choose between between:
void bar( foo const&, foo const& ) ;
template <>
void bar<baz>( baz cosnt&, foo const& ) ;
the C++ compiler will - all other things being equal - prefer the non-
template function over the template function.
So what makes this example interesting (and in fact counterintuitive),
is that the C++ compiler finds the call to bar() "ambiguous" - even
though one of the three bar() candidates is considered a better match
(being the only non-template function candidate) than the other two.
Or to put it another way, why is the non-template function a better
match than one other template function candidate - but not a better
match than two other template function candidates?
Greg