|
Boost Users : |
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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net