boost :: shared_ptr和std :: shared_ptr的同居

Ste*_*and 43 c++ boost shared-ptr c++11

我想boost::log在某些时候使用,但我不能传递std::shared_ptr一个参数,因为编译器(VS2010)无法将其转换为boost::shared_ptr.

我真的不喜欢他们是外星人的事实.

是否有一种安全透明的方式将一个转换为另一个,因为它们不会相互绊倒?

我不认为这两个问题都是相同的.

ron*_*nag 72

你可以这样做:

template<typename T>
boost::shared_ptr<T> make_shared_ptr(std::shared_ptr<T>& ptr)
{
    return boost::shared_ptr<T>(ptr.get(), [ptr](T*) mutable {ptr.reset();});
}

template<typename T>
std::shared_ptr<T> make_shared_ptr(boost::shared_ptr<T>& ptr)
{
    return std::shared_ptr<T>(ptr.get(), [ptr](T*) mutable {ptr.reset();});
}
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,这不适用于源ptr的弱引用.所以要小心那些!

  • +1哇,非常好的技巧,使用捕获按值来保留删除器lambda内部的原始`ptr`(以及因此另外的refcount)的副本.我不得不承认,我花了一段时间来弄明白这一点. (10认同)
  • @StephaneRolland lambda删除器存储为`boost :: shared_ptr`的成员,它又有一个`std :: shared_ptr`的副本作为成员(由于值为lambda的捕获),它增加了引用计算原始对象.因此每个`boost :: shared_ptr`通过其删除成员增加原始对象的引用计数.但是当`boost :: shared_ptr`(确实独立于`std` one)的引用计数达到0时,没有任何内容被删除,因为删除器是无操作,但是删除器的破坏实际上减少了原始的refcount. (5认同)
  • 如果存在缺陷,这种方法很有意思.删除器与计数一起保存,并在所有*strong*引用超出范围时执行.这种方法的问题在于,在存在"weak_ptr"的情况下,将调用删除器,并且不会发生任何事情,并且至少存在一个"weak_ptr",对象的生命周期将被引用人为地扩展.在删除器内部,打破了`weak_ptr` /`shared_ptr`combination组合的语义.修复很简单,设计很好,只需要改变实现:`[ptr](T*){ptr.reset();}` (5认同)
  • 究竟什么是构造函数的第二个参数?它看起来(从构造函数签名)就像它应该是一个删除器,但我不懂语法. (2认同)
  • @ronag现在不是lambda必须是'可变的'吗?(是的,[刚刚确认](http://coliru.stacked-crooked.com/a/cd36aba0db83d79c).) (2认同)
  • @DavidRodríguez-dribeas:我相信即使有你的修正,仍存在一个'weak_ptr`存在的缺陷.例如,如果你创建一个`std shared_ptr`,那么就使用上面的方法创建一个`boost :: shared_ptr`,然后在`boost :: shared_ptr`中创建一个`boost :: weak_ptr`,当`boost :: shared_ptr`被删除`weak_ptr`会认为对象不再存在(`weak_ptr.lock()`将返回`null`)即使实际对象(即原始的`std :: shared_ptr`)还存在. (2认同)