Как получить тип сравнения priority_queue?

Большинство подобных контейнеров имеют такие типы членов, как key_compare или value_compare, но там none для priority_queue.

Это потому, что priority_queue является адаптером? Или это по стандарту по ошибке?

Ответ 1

Да, это действительно странно и, похоже, является надзором в стандарте С++. В стандарте объявляется priority_queue как:

template <class T,
          class Container = vector<T>,
          class Compare = less<typename Container::value_type> >
class priority_queue;

И пока он указывает следующие публичные элементы:

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;

он по какой-то причине опускает объявление typedef Compare value_compare;. Стандартная библиотека С++ проблема для этого была отправлена ​​в Рабочую группу библиотеки (LWG) пользователем SO Columbo.

Обходные

Однако для решения этой проблемы вы можете использовать следующее.

В С++ 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;

Например:

#include <type_traits>

static_assert(
    std::is_same<
        GetCompare_t<std::priority_queue<int> >,
        std::less<int>
    >::value, "");

В С++ 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; };

Например:

int main() {
    return typename GetCompare<std::priority_queue<int> >::type()(42, 0);
}