Conversion from boost::shared_ptr to std::shared_ptr?

青春壹個敷衍的年華 提交于 2019-11-26 19:17:41

问题


I got a library that internally uses Boost's version of shared_ptr and exposes only those. For my application, I'd like to use std::shared_ptr whenever possible though. Sadly, there is no direct conversion between the two types, as the ref counting stuff is implementation dependent.

Is there any way to have both a boost::shared_ptr and a std::shared_ptr share the same ref-count-object? Or at least steal the ref-count from the Boost version and only let the stdlib version take care of it?


回答1:


You can carry the boost::shared_ptr "inside" the std::shared_ptr by using the destructor to carry the reference around:

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));

}

The only real reason to do this is if you have a bunch of code that expects std::shared_ptr<T>.




回答2:


Based on janm's response at first I did this:

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(); });
}

But then I realized I could do this instead:

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));
    }
}

This solution leaves no reason for not using it without restrictions since you get the original pointer back if you convert back to the original type.



来源:https://stackoverflow.com/questions/6326757/conversion-from-boostshared-ptr-to-stdshared-ptr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!