samedi 18 avril 2015

How does std::shared_ptr converts across class hierarchy when passing by reference?

Looking at 20.8.2.2 Class template shared_ptr [util.smartptr.shared] I realized that std::shared_ptr has template copy constructors and assignment operators that allow the conversion from shared_ptr<Derived> to shared_ptr<Base> if and only if Derived* is convertible to Base*. These conversion are done (in my understanding) only via the templated copy constructors and assignment operators. However, it seems I can also pass a shared_ptr<Derived> to a function that takes shared_ptr<Base>& (i.e., pass by reference). It seems that there should be an implicit conversion operator, but according to the standard there is none.


The code below clarifies what I mean:



#include <iostream>
#include <memory>

struct Base {};
struct Derived: Base {};

void f(const std::shared_ptr<Base>& ) {}

int main()
{
std::shared_ptr<Derived> spDerived(new Derived);

// conversion below is OK, via template copy ctor
std::shared_ptr<Base> spBase(spDerived);
// also OK, via template copy assignment operator
spBase = spDerived;

// why is this OK? Cannot see any conversion operators in
// 20.8.2.2 Class template shared_ptr [util.smartptr.shared]
f(spDerived);
}


My question: In this case, who's performing the conversion from shared_ptr<Derived> to shared_ptr<Base> in the call f(spDerived)? (for the compiler shared_ptr<Derived> has no relation whatsoever with shared_ptr<Base>, even if Derived is a child of Base)


Aucun commentaire:

Enregistrer un commentaire