我经常遇到需要一个存储 std::pair
、std::tuple
或 的优先级队列的问题>std::array
其中元素按该对的第一个条目排序。
例如,条目 [4, 2]
、[2, 4]
、[1, 1]
和 [3 , 3]
将排序为:
[1, 1]
[2, 4]
< [3, 3]
< [4, 2]
。
我最终弄清楚如何得到我想要的东西,但总是很混乱。我将在下面提供一些例子。
我可能会尝试类似的操作:
#include <queue>
struct SomeKindOfPair {
int ordered_element;
int unordered_element;
};
int main() {
std::priority_queue<SomeKindOfPair> my_queue([](SomeKindOfPair a, SomeKindOfPair b) {return a.ordered_element > b.ordered_element; });
return 0;
}
我的意图是使用 here 的构造函数 (2) 并允许编译器推断出 Comparer 类型。这将导致编译器抛出错误,我不确定为什么。为了完整起见,错误是
cannot convert argument 1 from 'main::<lambda_1>' to 'const _Pr &'
with _Pr=std::less<SomeKindOfPair>
这就是我已经开始工作的内容。正如您所看到的,这很混乱:
#include <queue>
struct SomeKindOfPair {
int ordered_element;
int unordered_element;
};
class MyComparer {
public:
bool operator()(SomeKindOfPair a, SomeKindOfPair b) {
return a.ordered_element > b.ordered_element;
}
};
int main() {
MyComparer comparer{};
std::priority_queue<SomeKindOfPair, std::vector<SomeKindOfPair>, MyComparer> my_queue{ comparer };
return 0;
}
有更好的方法吗?具体来说:
- 我可以在不定义
MyComparer
类的情况下执行此操作吗?
- 我可以在不必编写
priority_queue
、std::priority_queue、MyComparer>
的完整模板专业化的情况下执行此操作吗?
- 我可以做到这一点,而不必在任何地方命名比较运算符(将其定义为构造
priority_queue
的 lambda)吗?
而且,不太重要的是,
- 因为大多数在线法官仍然使用旧版本的 C++ 标准,我可以通过与旧 C++ 标准(特别是 C++14)兼容的方式来执行此操作吗?
- 如果这样做会在适用的情况下禁用概念,我可以在不使用
decltype
的情况下执行此操作吗?
I frequently come across the problem of needing a priority queue that stores std::pair<int, T>
, std::tuple<int, T>
, or std::array<int, 2>
where elements are ordered by the first entry of the pair.
For example, the entries [4, 2]
, [2, 4]
, [1, 1]
, and [3, 3]
would be ordered as:
[1, 1]
< [2, 4]
< [3, 3]
< [4, 2]
.
I eventually figure out how to get what I want, but it is always messy. I will provide some examples below.
I might try something like:
#include <queue>
struct SomeKindOfPair {
int ordered_element;
int unordered_element;
};
int main() {
std::priority_queue<SomeKindOfPair> my_queue([](SomeKindOfPair a, SomeKindOfPair b) {return a.ordered_element > b.ordered_element; });
return 0;
}
My intent here was to use constructor (2) from here and allow the Comparer type to be deduced by the compiler. This will cause the compiler to throw an error and I'm not sure why. For completeness, the error is
cannot convert argument 1 from 'main::<lambda_1>' to 'const _Pr &'
with _Pr=std::less<SomeKindOfPair>
This is what I have gotten to work. As you can see, it is messy:
#include <queue>
struct SomeKindOfPair {
int ordered_element;
int unordered_element;
};
class MyComparer {
public:
bool operator()(SomeKindOfPair a, SomeKindOfPair b) {
return a.ordered_element > b.ordered_element;
}
};
int main() {
MyComparer comparer{};
std::priority_queue<SomeKindOfPair, std::vector<SomeKindOfPair>, MyComparer> my_queue{ comparer };
return 0;
}
Is there a better way to do this? Specifically:
- Can I do this without defining a
MyComparer
class?
- Can I do this without having to write out the full template specialization of
priority_queue
, std::priority_queue<SomeKindOfPair, std::vector<SomeKindOfPair>, MyComparer>
?
- Can I do this without having to name the comparison operator anywhere (define it as a lambda where I construct the
priority_queue
)?
and, less importantly
- Because most online judges still use old versions of the C++ standard, can I do this in a way that is compatible with older C++ standards (in particular C++14)?
- Can I do this without using
decltype
, if doing so will disable the use of Concepts where applicable?
发布评论
评论(1)
您可以使用第一种形式的扣除指南来进行
std::priority_queue
:然后
演示
You can use the first form of the deduction guides for
std::priority_queue
:Then
Demo