如何在没有显式比较对象的情况下从 Container 对象构造 std::priority_queue 的实例?
Posted
技术标签:
【中文标题】如何在没有显式比较对象的情况下从 Container 对象构造 std::priority_queue 的实例?【英文标题】:How do I construct an instance of std::priority_queue from a Container object without an explicit Compare object? 【发布时间】:2021-07-06 11:42:51 【问题描述】:根据cppreference,std::priority_queue 被定义为三个参数的模板,T
、Container
和Compare
,其中最后两个具有基于T
的默认值:
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
现在假设我对这些默认值非常满意,并希望从现有的 std::vector<int>
对象构造一个 std::priority_queue<int>
对象。
我can最接近的是
priority_queue(const Compare& compare, Container&& cont);
它使用cont
移动构造底层容器,然后通过调用std::make_heap
对其进行堆化。
这一切都很好,但我必须明确提供一个 Compare
对象,即
std::vector<int> vec;
// filling vec with values
std::priority_queue<int> pqstd::less<int>(), std::move(vec);
为什么 std::priority_queue 没有类似的构造函数
priority_queue(const Container& cont);
priority_queue(Container&& cont);
这似乎是合理的,因为它有一个仅比较器的构造函数:
explicit priority_queue(const Compare& compare)
: priority_queue(compare, Container())
还是我错过了其他方法?
【问题讨论】:
没有。 std::priority_queue 在几个方面违反了最小惊讶原则。但这是很棒的课程,“std::less我认为您的要求是合理的,我也在考虑用例,但遗憾的是 STL 不支持它。然后我们可以考虑制作自己的包装器:我们只是继承priority_queue
,并进行强制转换:
#include <iostream>
#include <queue>
#include <vector>
template <typename T, typename Seq = std::vector<T>,
typename Cmp = std::less<typename Seq::value_type>>
class MyPriorityQueue : public std::priority_queue<T, Seq, Cmp>
public:
using base_t = std::priority_queue<T, Seq, Cmp>;
MyPriorityQueue() = default;
template <typename Cont>
MyPriorityQueue(Cont&& cont) : base_t(Cmp, std::move(cont))
template <typename Cont>
MyPriorityQueue(const Cont& cont) : base_t(Cmp, cont)
;
template <typename Cont, typename T = typename Cont::value_type,
typename Seq = std::vector<T>,
typename Cmp = std::less<typename Seq::value_type>>
std::priority_queue<T, Seq, Cmp> MakePriorityQueue(Cont&& cont)
return std::priority_queue<T, Seq, Cmp>(
MyPriorityQueue<T, Seq, Cmp>(std::move(cont)));
template <typename Cont, typename T = typename Cont::value_type,
typename Seq = std::vector<T>,
typename Cmp = std::less<typename Seq::value_type>>
std::priority_queue<T, Seq, Cmp> MakePriorityQueue(const Cont& cont)
return std::priority_queue<T, Seq, Cmp>(MyPriorityQueue<T, Seq, Cmp>(cont));
template <typename T, typename Seq = std::vector<T>,
typename Cmp = std::less<typename Seq::value_type>>
std::priority_queue<T, Seq, Cmp> MakePriorityQueue()
return std::priority_queue<T, Seq, Cmp>(MyPriorityQueue<T, Seq, Cmp>());
用法会很干净:
std::vector<int> vec;
auto pq = MakePriorityQueue(std::move(vec));
Online demo
【讨论】:
以上是关于如何在没有显式比较对象的情况下从 Container 对象构造 std::priority_queue 的实例?的主要内容,如果未能解决你的问题,请参考以下文章
JSON.NET:如何在没有数组的情况下从DataTable对象中仅序列化一行?
在没有第三方库的情况下从 JSON 获取动态对象的最佳方法是啥?