在模板类中使用std :: function <>

时间:2019-03-29 11:49:59

标签: c++ c++14

我遇到了以下队列模板类,

template <class T>
class Queue {
protected:
    // Data
    std::queue<T> queue_;
    typename std::queue<T>::size_type size_max_;

    // Thread gubbins
    std::mutex mutex_;
    std::condition_variable full_;
    std::condition_variable empty_;

    // Exit
    std::atomic_bool quit_{false};
    std::atomic_bool finished_{false};

public:
    Queue(const size_t size_max);

    bool push(T &&data);
    bool pop(T &data);

    // The queue has finished accepting input
    void finished();
    // The queue will cannot be pushed or popped
    void quit();
};



using intQueue = Queue<std::unique_ptr<int, std::function<void(int*)>>>

并且我不理解以上 using 语句中std::function<void(int*)>的使用。为什么我们不将其写为using intQueue = Queue<std::unique_ptr<int>>

2 个答案:

答案 0 :(得分:2)

std::unique_ptr实际上有两种类型:

  • 带有析构函数的唯一指针,该指针只需对拥有的指针调用delete
  • 带有自定义删除器的唯一指针

尽管它仍然是一个类模板,但是两种unique_ptr不可互换。因此,不能像unique_ptr这样定义的std::unique_ptr<int>来使用自定义删除器,而std::unique_ptr<int, std::function<void(int*)>>可以使用自定义删除器。

这与std::shared_ptr不同,std::shared_ptr<Book>实际上只有一种类型(当然是每个指针类型)。因此,您可以输入std::unique_ptr类型,并为其自定义删除。

之所以对unique_ptr进行更改,是为了最大程度地减少内存消耗。在几乎所有情况下,std::unique_ptr将使用默认的删除器,因此存储一个指针而不是2(删除器的第二个指针)就足够了。仅在使用deleter-template-argument实例化类模板的情况下,该类型将存储2个指针。

编辑: 当然,不要忘了Brian在下面的评论:不带自定义删除器的std::unique_ptr效率也更高,因为对删除器的调用是“硬编码的”,因此可以内联,而不会产生开销。虚拟调用自定义删除器。这使得此||像调用delete your own一样有效(而不会忘记调用它)。

答案 1 :(得分:0)

std::function<void(int*)>是一个对象,可以保存任何类似于“ void(int *)function”的值。值得注意的是,您可以更改std::function对象以在其生命周期内保留不同的功能和功能对象。

这里用作Deleter的(可选)std::unique_ptr类型参数,用于保留有关如何释放std::unique_ptr所保存的原始指针的知识。

将这些内容加在一起可以使以不同方式分配的int(需要不同的解除分配)出现在同一队列中。这与std::pmr容器类似。