$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2005-12-03 12:07:48
Steven Solie wrote:
>I don't understand why the following program doesn't compile when
>using smart_ptr but works fine with raw pointers:
>  
>
The reason is in the overloading resolution rules.
Simplified:
class C : class B : class A
(A is the ultimate base)
f(A*), f(B*)
f(new C) -> call f with C*. The ideal match has a C* parameter, that 
doesn't exist. The candidates are A* and B*. In the same inheritance 
hierarchy, the most derived class wins, thus the B* call is chosen.
f(smartptr<A>), f(smartptr<B>)
However, smart pointers can't be just cast to smart pointers to base 
classes by the language, this is done using a cast operator:
template<typename Target> operator smartptr<Target>() {
  return smartptr<Target>(myptr);
}
This is the typical implementation of such an operator. If myptr is 
convertible to Target*, the call will succeed. If not, an attempt to 
instantiate the operator will fail (but overload resolution that 
attempts to instantiate won't cause a build error due to SFINAE).
smartptr<C> thus can generate two valid operators: operator smartptr<A> 
and operator smartptr<B>. But as far as the language is concerned, these 
are no different from, say, operator int. They have equal rights, they 
aren't part of an inheritance hierarchy.
For this reason, f(smartptr<A>) and f(smartptr<B>) are equally possible 
as overload choices, and the compiler stops with an ambiguity error.
Sebastian Redl