2014-12-08 1 views
2
#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). 
} 

Может кто-нибудь объяснить мне, почему вызов г (spderived) вызывает неоднозначность между г (BOOL) и г (повышающее :: shared_ptr)?функция перегрузки ambiguty между BOOL и повышение :: shared_ptr <base> при вызове с усилением :: shared_ptr <derived>

Компиляция с GCC версии 4.6.3 дает следующие ошибки:

$ 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)

Примечание: Если добавить -std = C++ 11 компилируется нормально, но я использую C++ 98/C++ 03 , так что это действительно не помогает мне. Clang и VC создают аналогичную ошибку, скомпилированную под C++ 03.

+1

Это одна из тех вещей, которые C++ 11 «исправляет», да, ожидайте, что это будет немного противно работать в C++ 03! Вот почему у нас есть обновления в первую очередь. –

ответ

2

В C++ 03 shared_ptr имеет неявный оператор преобразования bool, в C++ 11 он явно. Этот вызов ambigious, поскольку в обоих случаях user-defined conversion будет называться, преобразование в BOOL, или преобразование в shared_ptr<base>, которая определяется следующим образом:

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 

это не конструктор копирования, это конструктор преобразования, поэтому цепь будет как это

tmp = shared_ptr<base>(spderived); 
b = shared_ptr<base>(tmp); 

есть только один способ сделать то, что вы хотите: построить временный типа shared_ptr<base>.

g(boost::shared_ptr<base>(spderived)); 

 Смежные вопросы

  • Нет связанных вопросов^_^