在C ++ 03中,我们没有unique_ptr
,所以我改用了tr1::shared_ptr
。
现在,在C ++ 11中,在这种情况下,我要替换这样的调用:
tr1::shared_ptr<X> o(new X);
使用
std::unique_ptr<X> o(new X);
不幸的是,由于某种原因,我无法替换包含删除器的情况,其中该删除器是一个函数:
void special_delete(Y *p) { ... }
tr1::shared_ptr<Y> o(new Y(), special_delete);
std::unique_ptr<Y> o(new Y(), special_delete); // does not compile
std::unique_ptr<Y, std::function<void(Y*)> > o(new Y(), special_delete); // this compiles
为什么会这样? 是否可以用unique_ptr构造函数替换所有shared_ptr构造函数的同类方法?
我创建了此,但是对此我并不感到十分满意。
template <class Y>
using unique_ptr_with_deleter = std::unique_ptr<Y, std::function<void(Y*)> >;
unique_ptr_with_deleter<Y> o(new Y(), special_delete); // this compiles
答案 0 :(得分:4)
shared_ptr
模板对删除程序进行类型擦除。您想要的任何一种删除器只有一个单一类型shared_ptr<T>
。这是一个非常笨重(且昂贵)的工具。
相比之下,unique_ptr
成为类型的删除器部分,因此没有动态调用开销。 unique_ptr<T, D>
几乎和原始指针一样便宜。
请注意,您可以根据{em> any 删除类型shared_ptr<T>
的{{1}}右值构造unique_ptr<T, D>
。
有关您的解决方案的随机评论:两种解决方案都不是很好。将函数指针用作删除器,不必要地使删除器成为unique_ptr状态的 dynamic 部分。 D
情况更糟,使用整个类型擦除的虚拟调度机制进行删除-请记住,您静态知道如何删除!
更好的解决方案是通过编写自己的类型,使删除器成为 type 的一部分,而不是值的一部分:
std::function
这样,整个删除逻辑在编译时就已知,并且可以尽可能内联,而无需 additional 函数间接调用。
答案 1 :(得分:2)
您应提供删除器类型
std::unique_ptr<Y, decltype(&special_delete)> o{new Y{}, &special_delete};
请注意,将tr1::shared_ptr<X> o(new X);
替换为std::unique_ptr<X> o(new X);
不是一个好主意,并且一般来说也不可行。 std::unique_ptr
更像是auto_ptr
的替代品。