Опущение параметра типа для большего шаблона в C ++ STL - PullRequest
0 голосов
/ 04 июня 2018

Вот строка кода, которую я прочитал в книге

priority_queue<IteratorCurrentAndEnd, vector<IteratorCurrentAndEnd>, greater<>> min_heap;

, где IteratorCurrentAndEnd - это класс, реализующий метод operator>.Почему мы можем иметь greater<> вместо greater<IteratorCurrentAndEnd>?Я проверил и прочитал что-то вроде этого,

template< class T = void >
struct greater;

Но я действительно не знаю, что это значит.Это связано с типом void?Что это на самом деле?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

До C ++ 14 std::greater<T> был шаблоном класса, основанным на одном явном параметре типа T.Это позволило только сравнить два равных типа.В противном случае при сравнении разных типов нужно было полагаться на преобразование, которое может не сработать в процессе вывода аргументов шаблона.

Это было исправлено в C ++ 14 в том смысле, что теперь также существует общее сравнение.двух разных типов.Вместо использования нового шаблона класса std::greater<T,U> (который, возможно, не будет обратно совместим и, конечно, также более сложен), используется специализация std::greater<void>, которой не было до C ++ 14.Тип void выбран именно по этой причине: поскольку он никогда не использовался до C ++ 14 - сравнение void s не имеет смысла - автоматически получается обратная совместимость и даже избегается введение нового шаблона класса.

Как описано в справочнике , std::greater<void> теперь является функтором, содержащим шаблон функции operator(), аналогичный

template< class T, class U>
constexpr auto operator()( T&& lhs, U&& rhs ) const
{
    return std::forward<T>(lhs) > std::forward<U>(rhs);
}

. Это реализует общее сравнение между двумятипы (и это почти то же самое, что можно было бы придумать в настоящее время).

0 голосов
/ 04 июня 2018

Да, это связано с void во фрагменте, но ничего особенного в void как в самом типе нет.Этот синтаксис говорит, что struct greater принимает один параметр шаблона (то есть тип), но он может быть опущен, а в случае его пропуска void используется в качестве этого типа.Это похоже на синтаксис значений по умолчанию для обычных функций:

void foo(int x = 7);

foo(5); // x = 5
foo(); // x = 7
...