如何获得priority_queue的比较类型?

Isa*_*ual 12 c++ priority-queue c++-standard-library language-lawyer

最相似的容器有会员类型,如key_comparevalue_compare但有没有priority_queue.

是因为priority_queue是适配器吗?或者这是错误的标准?

jot*_*tik 8

是的,这确实很奇怪,似乎是C++标准的疏忽.标准声明priority_queue为:

template <class T,
          class Container = vector<T>,
          class Compare = less<typename Container::value_type> >
class priority_queue;
Run Code Online (Sandbox Code Playgroud)

虽然它指定了以下公共成员:

typedef typename Container::value_type value_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::size_type size_type;
typedef Container container_type;
Run Code Online (Sandbox Code Playgroud)

它出于某种原因省略了typedef Compare value_compare;声明.针对此问题的 C++标准库问题已由SO用户Columbo提交给图书馆工作组(LWG).

解决方法

但是,您可以使用以下方法解决此问题.

在C++ 11及更高版本中

#include <queue>

template <typename> struct GetCompare;

template <typename T, typename Container, typename Compare>
struct GetCompare<std::priority_queue<T, Container, Compare> >
{ using type = Compare; };

template <typename T>
using GetCompare_t = typename GetCompare<T>::type;
Run Code Online (Sandbox Code Playgroud)

例如:

#include <type_traits>

static_assert(
    std::is_same<
        GetCompare_t<std::priority_queue<int> >,
        std::less<int>
    >::value, "");
Run Code Online (Sandbox Code Playgroud)

在C++ 03及更早版本中

#include <queue>

template <typename> struct GetCompare;

template <typename T, typename Container, typename Compare>
struct GetCompare<std::priority_queue<T, Container, Compare> >
{ typedef Compare type; };
Run Code Online (Sandbox Code Playgroud)

例如:

int main() {
    return typename GetCompare<std::priority_queue<int> >::type()(42, 0);
}
Run Code Online (Sandbox Code Playgroud)