如何让shared_ptr包装类与make_shared一起使用

3
这个问题是对Customising std::shared_ptr or boost::shared_ptr to throw an exception on NULL dereference的扩展。
我需要一个类,它的行为类似shared_ptr,但在解引用nullptr时抛出异常。在上面的问题中,建议创建一个包含shared_ptr的包装类,并使该包装类抛出异常。
然而,我也想继续使用make_shared。有没有办法让make_shared与我的(或任何)shared_ptr包装类一起工作?类似于这样的东西:
checked_shared_ptr<MyClass> csp = make_checked_shared<MyClass>(...);

我猜你是要从shared_ptr继承,并提供构造函数和赋值运算符(用于拷贝和移动),这些构造函数和赋值运算符接受一个shared_ptr&作为参数。 - Jonathan Potter
或者对包装器(wrapper)做同样的事情?也许可以为这个新类型专门定制make_shared函数? - Martin Prazak
@martin_pr,你不能编写函数模板的部分特化,你需要在自己的命名空间中重载它。 - Jonathan Wakely
@JonathanWakely 嗯,好的,我错了... - Martin Prazak
1个回答

6

添加适当的构造函数

最简单的解决方案是在template<class T> class checked_shared_ptr中添加一个构造函数,以便可以使用std::shared_ptr<T>进行初始化,这将使下面的代码编译通过(并执行预期的操作)。

checked_shared_ptr<MyClass> csp = std::make_shared<MyClass> (...);

示例实现

template<class T>
struct checked_shared_ptr {

  template<
    class U,
    class = decltype (std::shared_ptr<T> (std::shared_ptr<U> {}))
  > checked_shared_ptr (std::shared_ptr<U> const& src)
    : _sptr (src)
  { }

  // ...

  T& operator* () {
    if (_sptr)
      return *_sptr;

    throw std::runtime_error ("nullptr");
  }

  // ...

  std::shared_ptr<T> _sptr;
};

checked_shared_ptr<MyClass> csp = std::make_shared<MyClass> ();

Note:
使用decltype(std::shared_ptr<T> (std::shared_ptr<U>))的原因是,只有当可以将U*转换为T*时,构造函数才参与重载决策。
相关链接:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接