将 std::shared_ptr<Derived> 转换为 const <Base>shared_ptr&

convert std::shared_ptr<Derived> to const shared_ptr<Base>&

本文关键字:gt ptr lt shared const Base Derived std 转换      更新时间:2023-10-16

如果我没记错的话(根据这个问题(,std::shared_ptr<Derived>不能绑定到const std::shared_ptr<Base>&。但是当我尝试以下代码时,它甚至没有给我任何警告。

#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
    //*/
}

编译器与标志-std=c++14 -Wall -Wextra -pedantic -Werror mingw g++ 5.3.0

与Coliru和许多其他在线编译器的结果相同。

我错过了什么吗?

std::shared_ptr有一个构造函数,允许从B转换为A

(来自CPP首选项(

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

9( 构造一个共享由 r 管理的对象的所有权的shared_ptr。如果r不管理任何对象,*this也不管理任何对象。如果模板重载不能隐式转换为T*,则模板重载不参与重载解析Y*


DoC(c)会给你一个错误,因为你没有定义一个执行转换的构造函数 - 不会为你隐式生成类似的构造函数。

除了已经回答的内容外,我还想指出传递给函数的是临时shared_ptr。有问题的代码之所以有效,是因为它是一个可以绑定临时代码的const shared_ptr&

<小时 />
#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