我遇到了以下队列模板类,
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>>
。
答案 0 :(得分:2)
std::unique_ptr
实际上有两种类型:
尽管它仍然是一个类模板,但是两种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
容器类似。