c++ - 如何在没有显式比较对象的情况下从 Container 对象构造 std::priority_queue 的实例?
问题描述
根据cppreference, std::priority_queue 被定义为三个参数的模板T
,Container
和Compare
,其中最后两个具有基于的默认值T
:
class Container = std::vector<T>,
class Compare = std::less<typename Container::value_type>
现在假设我对这些默认值非常满意,并希望std::priority_queue<int>
从现有对象构造一个对象std::vector<int>
。
我能拥有的最接近的是
priority_queue(const Compare& compare, Container&& cont);
它使用移动构造底层容器cont
,然后通过调用std::make_heap
.
一切都很好,但我必须明确提供一个Compare
对象,即
std::vector<int> vec;
// filling vec with values
std::priority_queue<int> pq{std::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()) { }
还是我错过了其他方法?
解决方案
I think your requirement is reasonable and I was considering the use case too, but sadly the STL doesn't support it. Then we can consider making our own wrapper: We just inherit the priority_queue
, and make a cast:
#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>());
}
The usage would be clean:
std::vector<int> vec;
auto pq = MakePriorityQueue(std::move(vec));
推荐阅读
- c++ - 如何使用 std::vector 返回 WCHAR ** 参数?
- java - 未记录的 API 声纳规则在 sonarqube 6.5 中不起作用?
- types - DAML 是否有 Hoogle 等价物?
- python - 为什么不在我的所有列表上运行这个循环?
- c++ - 如何将二叉树附加到另一个
- ruby-on-rails - 防止 nginx 删除 rack-cors 设置的 CORS 标头
- javascript - 如何在 vue 中删除图像时使输入类型文件为空?
- python-3.x - 将熊猫转换为 excel 的十进制值到逗号
- azure-devops - 如何覆盖 BTDF 设置文件名?
- react-native - 滑动时删除不会关闭 Swipeable React 本机