Reputation: 10591
If I remember correctly (and according to this question), std::shared_ptr<Derived>
cannot be bind to const std::shared_ptr<Base>&
. But when I tried the following code, it doesn't give me even any warnings.
#include <memory>
struct A{};
struct B:A{};
void Do(const std::shared_ptr<A>&){}
template<typename T>
struct C{};
void DoC(const C<A>&){}
int main()
{
std::shared_ptr<B> b = std::make_shared<B>();
Do(b); //accept ?
/*following lines generate error
C<B> c;
DoC(c); //error
//*/
}
compiler is mingw g++ 5.3.0
with flag -std=c++14 -Wall -Wextra -pedantic -Werror
Same result with Coliru and many other online compiler.
Is there something I missed?
Upvotes: 2
Views: 1000
Reputation: 10591
In addition to what already answered, I'd like to point out what passed to the function is a temporary shared_ptr
. The code in question works because it's a const
shared_ptr&
which can bind a temporary.
#include <memory>
struct A{};
struct B:A{};
void Do(const std::shared_ptr<A>&){}
void DoNo(std::shared_ptr<A>&){}
void DoRvalue(std::shared_ptr<A>&&){}
void DoValue(std::shared_ptr<A>){}
int main()
{
std::shared_ptr<B> b = std::make_shared<B>();
Do(b); // a temporary is constructed and passed to Do
DoNo(b); // not work, temporary cannot bind to lvalue reference
DoRvalue(b); // OK, temporary bind to rvalue reference
DoValue(b); // OK
}
https://godbolt.org/z/sW8cf5ohe
Upvotes: 1
Reputation: 93274
std::shared_ptr
has a constructor that allows the conversion from B
to A
:
(from cppreference)
template< class Y > shared_ptr( const shared_ptr<Y>& r );
9) Constructs a
shared_ptr
which shares ownership of the object managed byr
. Ifr
manages no object,*this
manages no object too. The template overload doesn't participate in overload resolution ifY*
is not implicitly convertible toT*
.
DoC(c)
gives you an error because you haven't defined a constructor that does the conversion - a similar constructor will not be implicitly generated for you.
Upvotes: 4