#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
struct base {};
struct derived : public base {};
void g(bool b) {}
void g(boost::shared_ptr<base> b) {}
int main()
{
boost::shared_ptr<base> spbase = boost::make_shared<derived>();
boost::shared_ptr<derived> spderived = boost::make_shared<derived>();
g(true); // ok
g(spbase); //ok
g(boost::static_pointer_cast<base>(spderived)); // ok
g(spderived); // I am ambiguous between g(bool b) and g(boost::shared_ptr<base> b).
}
Can someone explain to me why the call to g(spderived) causes a ambiguity between g(bool) and g(boost::shared_ptr)?
Compiling with gcc version 4.6.3 gives following error:
$ g++ shared_test.cpp -I/c/thirdparty/boost_1_55_0/ -o shared_test shared_test.cpp: In function 'int main()': shared_test.cpp:27:13: error: call of overloaded 'g(boost::shared_ptr&)' is ambiguous shared_test.cpp:27:13: note: candidates are: shared_test.cpp:7:6: note: void g(bool) shared_test.cpp:9:6: note: void g(boost::shared_ptr)
Note: If I add -std=c++11 it compiles fine, but I use c++98/c++03, so this doesn't really help me. Clang and VC produce a similar error, compiled under c++03.
In C++03 shared_ptr
has implicit bool conversion operator, in C++11 it's explicit. This call is ambigious, since in both cases user-defined conversion
will be called, conversion to bool, or conversion to shared_ptr<base>
, that is defined like this:
template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
shared_ptr( shared_ptr<Y> const & r,
typename boost::detail::sp_enable_if_convertible<Y,T>::type =
boost::detail::sp_empty() )
#else
shared_ptr( shared_ptr<Y> const & r )
#endif
it's not copy constructor, it's conversion constructor, so chain will be like this
tmp = shared_ptr<base>(spderived);
b = shared_ptr<base>(tmp);
there is only one way to do what you want: construct temporary of type shared_ptr<base>
.
g(boost::shared_ptr<base>(spderived));