如何创建一个将std::unique_ptr作为模板参数正常工作的容器?

How do I create a container that will work properly with std::unique_ptr as a template parameter?

本文关键字:常工作 参数 工作 创建 何创建 一个 ptr unique std      更新时间:2023-10-16

假设我有一个名为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<>,但我很难辨别实现的哪些部分与智能指针的正常工作相关。如有任何参考或链接,将不胜感激。

如果您只是想用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的客户端可以访问对deleter的引用(通过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;
};