David A. Greene wrote:
On Friday 21 May 2010 20:54:25 David A. Greene wrote:
What's the rationale for the enable_if'd constructor? Is BOOST_SP_NO_SP_CONVERTIBLE an official part of the library? Apparently it is causing gcc to check all doSomething members of Action against shared_ptr<Wrapper<B> > and those checks are causing instantiations of Wrapper<A>.
Urk. I just found out. The attached test does not compile with BOOST_SP_NO_SP_CONVERTIBLE because it renders shared_ptr unable to construct pointer-to-base from pointer-to-derived.
I see why your original test doesn't compile, but I don't see why this one should not. The only error I get with g++ is testbed.cpp:33: error: operands to ?: have different types `boost::shared_ptr<Base>' and `boost::shared_ptr<A>' and when I insert a conversion to shared_ptr<Base> to make them the same type, it compiles. Defining BOOST_SP_NO_SP_CONVERTIBLE will break other cases such as void foo( shared_ptr<Base> ); void foo( shared_ptr<int> ); // 'int' stands for an unrelated type and then calling foo with shared_ptr<A>. A similar scenario occurs if in your original example the functions are changed to take shared_ptr<const Wrapper<A>> and shared_ptr<const Wrapper<B>>, respectively. FWIW, I believe that you original example can be rejected by a compiler even with BOOST_SP_NO_SP_CONVERTIBLE defined. I don't think that the compiler is required to short-circuit overload resolution when it sees an exact match. It may well proceed to instantiate shared_ptr<Wrapper<A>> in order to see whether the argument can be converted to it (even though it's clear at this point that the conversion sequence will contain a user-defined conversion).