【问题标题】:What are the template parameters of std::priority_queue?std::priority_queue 的模板参数是什么?
【发布时间】:2020-10-13 12:53:37
【问题描述】:

我正在查看一些 STL 文档。我看到按降序存储的优先级队列的语法是:

std::priority_queue<int> q ;
//gives 9 8 7 6 5 4 3 2 1  when pushed and obtained

但是,对于以升序方式存储,它是:

std::priority_queue< int, std::vector<int>, std::greater<int> > q ;
//gives 1 2 3 4 5 6 7 8 9 when pushed and obtained

我想知道第二个例子中额外模板参数的具体用途是什么。例如,std::vector&lt;int&gt; 在该示例中做了什么?

另外,有人可以进一步解释这个声明吗?

priority_queue< pair<int ,int > , vector< pair<int ,int > > , greater< pair<int ,int > > > q ;

【问题讨论】:

  • 在 C++ 中,如果不设置前面的参数,则无法设置第三个参数。

标签: c++ c++11 vector stl priority-queue


【解决方案1】:

std::priority_queue 本身不是一个容器,它是一个容器适配器,这意味着它在内部使用另一个容器来存储队列中的实际数据。

默认情况下,它使用队列中存储的类型的std::vector

这里的问题是,就像将参数传递给带有默认参数的函数一样,您不能跳过模板列表中的参数,即使它们具有默认类型,您必须始终提供前面的模板参数。

如果您看到链接引用,您将看到std::priority_queue 的第二个和第三个模板参数具有默认类型。如果要更改第三个模板参数,还必须提供第二个模板参数,它是实际的底层容器。因此,对于int 中的std::priority_queue,您需要提供std::vector&lt;int&gt;


然而,有一种方法可以不将比较器的类型作为模板参数传递,std::priority_queue constructor 还为比较器函数采用(可选)参数。在这里你可以提供任何函数、函数对象、lambda或其他可调用对象。

在你的情况下,你可以这样做,例如

std::priority_queue<int> q{std::greater<int>()};

上述声明创建了一个std::greater&lt;int&gt; 对象并将其作为比较器传递给std::priority_queue 构造函数。

【讨论】:

  • 为什么第一个例子中不需要指定向量呢!?
  • @saru95 因为它有一个默认类型,请参阅链接参考。
  • 那么,您是说在第一种情况下默认使用向量,但在第二种情况下,由于greater,我们必须明确指定它?
  • @saru95 没错。但是,还有另一种传递比较器的方法,请参阅我的更新答案。
  • 投反对票,因为:1) std::priority_queue&lt;int&gt; q(std::greater&lt;int&gt;()); 将被解析为函数指针声明,而不是对象构造函数 2) std::priority_queue 没有你是构造函数左右;它只接受Compare 类型的比较器,默认为std::less&lt;T&gt;。您必须指定不同的比较器类型作为模板参数才能使其工作。
【解决方案2】:
template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

std::priority_queue 是一个包装另一个容器的容器,这意味着它只在另一个容器之上提供priorityqueue 抽象,只要这个与SequenceContainer concept 匹配。

如果用户想要不同的时间和内存复杂性约束,则可以更改容器。或者提供自己的容器。

std::greater&lt;T&gt;T 类型元素的比较器。要求满足全序。

【讨论】:

    猜你喜欢
    • 2021-06-10
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多