C ++ 0x Hiba: túlterhelés funkció std :: shared_ptr a const érv kétértelmű

szavazat
6

Tegyük fel, hogy van két független osztályok Aés B. Nekem is van egy osztály Bla, amely boost::shared_ptra következő:

class Bla {
public:
    void foo(boost::shared_ptr<const A>);
    void foo(boost::shared_ptr<const B>);
}

Figyeljük meg a const . Ez a fontos rész, amely az eredeti változata a kérdés hiányzott. Ez lefordítja, és a következő kód működik:

Bla bla;
boost::shared_ptr<A> a;
bla.foo(a);

Azonban, ha váltani a boost::shared_ptrhasználata std::shared_ptra fenti példákban, kapok egy fordítási hibát, hogy azt mondja:

error: call of overloaded 'foo(std::shared_ptr<A>)' is ambiguous
note: candidates are: void foo(std::shared_ptr<const A>)
                      void foo(std::shared_ptr<const B>)

Tudna segíteni nekem kitalálni, hogy miért a fordító nem tudja kitalálni, melyik működik, hogy használja a std :: shared_ptr esetében, és a boost :: shared_ptr esetben? Én az alapértelmezett GCC és a Boost verzió az Ubuntu 11.04 csomag lerakat, amelyek jelenleg GCC 4.5.2 és a Boost 1.42.0.

Itt van a teljes kódot, amit megpróbál összeállítása:

#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
// #include <memory>
// using std::shared_ptr;

class A {};
class B {};

class Bla {
public:
    void foo(shared_ptr<const A>) {}
    void foo(shared_ptr<const B>) {}
};

int main() {
    Bla bla;
    shared_ptr<A> a;

    bla.foo(a);

    return 0;
}

By the way, ez a kérdés arra ösztökélt, hogy kérje ezt a kérdést arról, hogy kéne használni std::shared_ptrmég egyáltalán ;-)

A kérdést 12/06/2011 13:04
a forrás felhasználó
Más nyelveken...                            


4 válasz

szavazat
6

A következő lefordul GCC 4.5 és a Visual Studio 10. Ha azt mondják, hogy nem fordul a GCC 4.5.2 akkor úgy hangzik, mint egy fordító hibát, ami akkor jelentsd (győződjünk meg róla, hogy valóban történik, akkor nagyobb a valószínűsége, hogy amit tett valamiféle elírás).

#include <memory>
class A{};
class B{};
class Bla {
public:
    void foo(std::shared_ptr<A>) {}
    void foo(std::shared_ptr<B>) {}
};

int main()
{
    Bla bla;
    std::shared_ptr<A> a;
    bla.foo(a);
}
Válaszolt 12/06/2011 13:11
a forrás felhasználó

szavazat
7

shared_ptrvan egy sablon egyargumentumú kivitelező, mely még ma is az átalakítás itt. Ez az, amit lehetővé teszi a tényleges paraméter shared_ptr<Derived>kell megadni, ahol a shared_ptr<Base>van szükség.

Mivel mind shared_ptr<const A>és shared_ptr<const B>ezt implicit konverzió, ez egyértelmű.

Legalábbis C ++ 0x, a szabvány előírja, hogy shared_ptrhasználat néhány SFINAE trükk, hogy megbizonyosodjon arról, hogy a sablon konstruktor csak akkor egyezik típusok, amelyek ténylegesen lehet alakítani.

Az aláírás (lásd [util.smartptr.shared.const]):

shared_ptr<T>::shared_ptr(const shared_ptr<T>& r) noexcept;
template<class Y> shared_ptr<T>::shared_ptr(const shared_ptr<Y>& r) noexcept;

Szükséges: A második konstruktor nem vesz részt a túlterhelés felbontás hacsak Y*implicite átalakítható T*.

Lehetséges, hogy a könyvtár még nem lett frissítve eleget ennek a kötelezettségének. Lehet, hogy megpróbál egy újabb verziója libc ++.

Boost nem fog működni, mert nem tartalmazza ezt a követelményt.

Itt egy egyszerűbb teszt: http://ideone.com/v4boA (Ez a teszt sikertelen lesz a megfelelő fordítót, ha lefordul sikeresen, azt jelenti, az eredeti ügy akkor hibásan jelentett egyértelmű.)

VC ++ 2010 lesz ez jobb (a std::shared_ptr).

Válaszolt 12/06/2011 18:31
a forrás felhasználó

szavazat
2

Használhatja std::static_pointer_casthozzá a constképzettsége:

bla.foo(std::static_pointer_cast<const A>(a));
Válaszolt 12/06/2011 19:18
a forrás felhasználó

szavazat
0

http://bytes.com/topic/c/answers/832994-shared_ptr-derived-classes-ambiguitity-overloaded-functions

struct yes_type { char dummy; };
struct no_type { yes_type a; yes_type b; };

template < typename From, typename To >
class is_convertible
{
    private:
        static From* dummy ( void );

        static yes_type check ( To );

        static no_type check ( ... );

    public:

        static bool const value = sizeof( check( *dummy() ) ) == sizeof( yes_type );

}; // is_convertible

Egy boost a shared_ptr.h módosítsa a kivitelező aláírás:

template<class Y>
shared_ptr(shared_ptr<Y> const & r,
    typename enable_if<is_convertible<Y*, T*>::value, void*>::type = 0
    ): px(r.px), pn(r.pn) // never throws
{
}
Válaszolt 01/01/2012 08:59
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more