如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?
Posted
技术标签:
【中文标题】如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?【英文标题】:How do I create a container that will work properly with std::unique_ptr as a template parameter? 【发布时间】:2011-12-01 13:44:31 【问题描述】:假设我有一个名为 MQueue 的互斥队列:
#include <deque>
template< typename T >
class MQueue
public:
T* pop()
lock();
T* ptr = nullptr;
// get it out of m_dq...
unlock();
return ptr;
// push, etc... and other methods
private:
std::deque<T*> m_dq;
;
以下实例已经过测试并且工作正常:
MQueue< int > my_simple_mq;
我需要对 MQueue 进行哪些修改以确保
MQueue< std::unique_ptr< int > > my_smart_mq;
行为会正常吗?我试图将代码浏览到 std::vector 以供参考,但我很难辨别实现的哪些部分与智能指针的正常工作相关。任何参考或链接将不胜感激。
【问题讨论】:
没有这些细节就无法判断。为什么要存储T*
,以及如何存储?您想要T = unique_ptr<U>
,还是想要替换 T*
为unique_ptr<T>
?
我完全愿意将 T* 内部实现更改为其他内容。目前,MQueue 实例拥有它的所有条目,因此在销毁时对它们调用 delete。这意味着,如果我只想让调用者工作,我可以在正确的位置用 unique_ptrdeque
已经拥有它的内容),但也许你'会觉得this article by Herb Sutter很有趣。
你为什么不按值存储和返回东西?
@kfmfe04 移动语义是你的朋友 :) 这就是你防止昂贵复制的方法。
【参考方案1】:
如果您只想用unique_ptr<T>
替换T*
,那么它看起来像:
template< typename T >
class MQueue
public:
std::unique_ptr<T> pop()
lock();
std::unique_ptr<T> ptr = std::move(m_dq.back());
m_dq.pop_back();
unlock();
return ptr;
// push, etc... and other methods
private:
std::deque<std::unique_ptr<T>> m_dq;
;
但是在阅读您在问题中的评论时,现在尚不清楚您要问的是什么。如果您希望 unqiue_ptr
有时拥有指针而有时不拥有,您可以编写一个自定义删除器,其中包含一个标志,说明它是否应该删除指针。 unique_ptr
的客户端可以访问对删除器的引用(通过 get_deleter()
访问器)以检查/更改该标志。
这是一个示例(未经测试)代码,展示了它的外观:
template <class T>
class my_deleter
bool owns_;
public:
explicit my_deleter(bool owns) : owns_(owns)
bool owns() const return owns_;
void set_owns(bool owns) owns_ = owns;
void operator()(T* p) if (owns_) delete p;
;
template< typename T >
class MQueue
public:
typedef std::unique_ptr<T, my_deleter<T>> Ptr;
Ptr pop()
lock();
Ptr ptr = std::move(m_dq.back());
m_dq.pop_back();
unlock();
return ptr;
// push, etc... and other methods
private:
std::deque<Ptr> m_dq;
;
【讨论】:
ty - 实际上 get_deleter() 提示是我正在寻找的(我知道如何在 MQueue 中使用 unique_ptr - 相反,我试图弄清楚如何允许用户通过传入/不传入 unique_ptr 作为实例化参数)。 如果它可能拥有或不拥有它 std::shared_ptr 会更有意义以上是关于如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?的主要内容,如果未能解决你的问题,请参考以下文章
使用已使用 new X() 创建的变量将 std::unique_ptr 传递给函数
如何将 std::sort() 与 std::unique_ptr<[]> 一起使用?
std::将 std::unique_ptr 移动到 stl 容器中。 (MSVC 编译器问题)