【问题标题】:Conversion from boost::shared_ptr to std::shared_ptr?从 boost::shared_ptr 到 std::shared_ptr 的转换?
【发布时间】:2011-09-13 16:21:09
【问题描述】:

我有一个库,它在内部使用 Boost 的 shared_ptr 版本并且只公开那些。对于我的应用程序,我想尽可能使用std::shared_ptr。遗憾的是,这两种类型之间没有直接的转换,因为引用计数的东西是依赖于实现的。

有没有办法让boost::shared_ptrstd::shared_ptr 共享同一个引用计数对象?或者至少从 Boost 版本中窃取引用计数,只让 stdlib 版本处理它?

【问题讨论】:

  • 我看不出混合来自不同库的内存管理的理由。可能存在指向 boost:shared_ptr 的内部对象链接,如果您接管了引用计数,则需要确保更新反映在您的 std::shared_ptr 上

标签: c++ boost shared-ptr std


【解决方案1】:

根据 janm 最初的回复,我这样做了:

template<class T> std::shared_ptr<T> to_std(const boost::shared_ptr<T> &p) {
    return std::shared_ptr<T>(p.get(), [p](...) mutable { p.reset(); });
}

template<class T> boost::shared_ptr<T> to_boost(const std::shared_ptr<T> &p) {
    return boost::shared_ptr<T>(p.get(), [p](...) mutable { p.reset(); });
}

但后来我意识到我可以这样做:

namespace {
    template<class SharedPointer> struct Holder {
        SharedPointer p;

        Holder(const SharedPointer &p) : p(p) {}
        Holder(const Holder &other) : p(other.p) {}
        Holder(Holder &&other) : p(std::move(other.p)) {}

        void operator () (...) { p.reset(); }
    };
}

template<class T> std::shared_ptr<T> to_std_ptr(const boost::shared_ptr<T> &p) {
    typedef Holder<std::shared_ptr<T>> H;
    if(H *h = boost::get_deleter<H>(p)) {
        return h->p;
    } else {
        return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
    }
}

template<class T> boost::shared_ptr<T> to_boost_ptr(const std::shared_ptr<T> &p){
    typedef Holder<boost::shared_ptr<T>> H;
    if(H * h = std::get_deleter<H>(p)) {
        return h->p;
    } else {
        return boost::shared_ptr<T>(p.get(), Holder<std::shared_ptr<T>>(p));
    }
}

这个解决方案没有理由不使用它,因为如果你转换回原始类型,你会得到原始指针。

【讨论】:

【解决方案2】:

您可以通过使用析构函数将引用携带在 std::shared_ptr “内部”携带 boost::shared_ptr:

template<typename T>
void do_release(typename boost::shared_ptr<T> const&, T*)
{
}

template<typename T>
typename std::shared_ptr<T> to_std(typename boost::shared_ptr<T> const& p)
{
    return
        std::shared_ptr<T>(
                p.get(),
                boost::bind(&do_release<T>, p, _1));

}

这样做的唯一真正原因是如果您有一堆代码需要std::shared_ptr&lt;T&gt;

【讨论】:

  • 说实话,一开始我并没有完全理解您所说的“随身携带参考资料”是什么意思,但这确实是一个非常简洁的问题,谢谢。 :)
猜你喜欢
  • 2011-09-13
  • 2011-09-27
  • 2013-06-12
  • 2013-04-16
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
相关资源
最近更新 更多