我有一个内部使用Boost的shared_ptr
版本的库,只公开那些。对于我的应用程序,我尽可能使用std::shared_ptr
。遗憾的是,这两种类型之间没有直接转换,因为引用计数是依赖于实现的。
有没有办法让boost::shared_ptr
和std::shared_ptr
共享同一个ref-count-object?或者至少从Boost版本中窃取引用计数,只让stdlib版本处理它?</ p>
答案 0 :(得分:35)
根据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));
}
}
此解决方案没有理由不使用它而没有限制,因为如果转换回原始类型,则会返回原始指针。
答案 1 :(得分:28)
你可以在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<T>
的代码。