构建一个对的priority_queue

发布于 2025-01-11 04:15:49 字数 2149 浏览 0 评论 0 原文

我经常遇到需要一个存储 std::pairstd::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;
}

有更好的方法吗?具体来说:

  1. 我可以在不定义 MyComparer 类的情况下执行此操作吗?
  2. 我可以在不必编写 priority_queuestd::priority_queue、MyComparer> 的完整模板专业化的情况下执行此操作吗?
  3. 我可以做到这一点,而不必在任何地方命名比较运算符(将其定义为构造 priority_queue 的 lambda)吗?

而且,不太重要的是,

  1. 因为大多数在线法官仍然使用旧版本的 C++ 标准,我可以通过与旧 C++ 标准(特别是 C++14)兼容的方式来执行此操作吗?
  2. 如果这样做会在适用的情况下禁用概念,我可以在不使用 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:

  1. Can I do this without defining a MyComparer class?
  2. Can I do this without having to write out the full template specialization of priority_queue, std::priority_queue<SomeKindOfPair, std::vector<SomeKindOfPair>, MyComparer>?
  3. 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

  1. 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)?
  2. Can I do this without using decltype, if doing so will disable the use of Concepts where applicable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

罪歌 2025-01-18 04:15:49

您可以使用第一种形式的扣除指南来进行 std::priority_queue

template <class Comp, class Container>
priority_queue(Comp, Container)
 -> priority_queue<typename Container::value_type, Container, Comp>;

然后

std::vector<SomeKindOfPair> v;
std::priority_queue my_queue(
  [](const auto& a, const auto& b) {return a.ordered_element > b.ordered_element; }, v);

演示

You can use the first form of the deduction guides for std::priority_queue:

template <class Comp, class Container>
priority_queue(Comp, Container)
 -> priority_queue<typename Container::value_type, Container, Comp>;

Then

std::vector<SomeKindOfPair> v;
std::priority_queue my_queue(
  [](const auto& a, const auto& b) {return a.ordered_element > b.ordered_element; }, v);

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文