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

后端 未结 2 1186
醉酒成梦
醉酒成梦 2020-12-04 15:37

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 wh

相关标签:
2条回答
  • 2020-12-04 16:11

    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>.

    0 讨论(0)
  • 2020-12-04 16:21

    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.

    0 讨论(0)
提交回复
热议问题