在初始化列表中转换 shared_ptr

Casting shared_ptr in initializer list

是否可以向上转换初始化列表中的共享指针对象引用?

我有两个 class 层次结构,它们具有匹配的派生 classes。假设我有一个 Base class 派生到 FooBar class。然后我有一个单独的层次结构 ProxyBase class 然后(为了匹配其他层次结构)有 FooProxyBarProxy.

ProxyBase class 存储一个 shared_ptr<Base>。创建 ProxyFoo 时需要 std::shared_ptr<Foo>&,创建 ProxyBar 时需要 std::shared_ptr<Bar>&.

我可以通过两种方式完成这项工作:

但我想知道这是否可以通过引用来完成。

认为 我知道问题出在哪里:当我删除引用时它起作用了,我认为那是因为 "casting" a shared_ptr<X> 在技术上是不允许;它只能通过创建 derived/base 类型的新 shared_ptr 对象来 "casted"。当使用引用时,人们试图将一个 shared_ptr 对象实际转换为另一个对象,这是不允许的。这是正确的吗?

最初我认为这是 std::static_pointer_cast 会有所帮助的情况之一,但如果我的假设是正确的,那也无济于事。

独立示例:

#include <memory>

class Base { };

class Foo : public Base
{
private:
  int val_;

public:
  Foo(int val) : val_(val) { }
};

class ProxyBase
{
protected:
  std::shared_ptr<Base> obj_;

  ProxyBase(std::shared_ptr<Base>& obj) : obj_(obj) { }
};

class FooProxy : public ProxyBase
{
public:
  FooProxy(std::shared_ptr<Foo>& fobj) : ProxyBase(fobj) { }
};

int main()
{
  auto f = std::make_shared<Foo>(42);
  auto fp = std::make_shared<FooProxy>(f);
}

所以我的问题归结为:是否可以在不删除引用的情况下在上面的(当前非功能性)代码中执行我正在尝试执行的操作,同时保留 FooBar FooProxyBarProxy?

的特定构造函数

一个shared_ptr<Derived>可以转换到一个shared_ptr<Base>,但不是一个shared_ptr<Base>.

换句话说,编译:

std::shared_ptr<Derived> pd;
std::shared_ptr<Base> pb = pd;

但这不是:

std::shared_ptr<Base>& pb = pd;

但这确实如此,因为 const 引用可以绑定到临时对象,这将隐式执行转换:

std::shared_ptr<Base> const& pb = pd;

问题是您在构造函数中使用了非常量左值引用。您应该采用 const 左值引用或仅按值采用它们。