Почему тип функции сравнения необходимо указывать в качестве параметра шаблона? - PullRequest
0 голосов
/ 30 сентября 2019

Для ассоциативных контейнеров в C ++, таких как set, map и т. Д., Нам необходимо предоставить пользовательский тип компаратора ключей в качестве параметра шаблона следующим образом.

bool compareMyType(const MyType& a, const MyType& b);

set<MyType, decltype(compareMyType)*> my_set(compareMyType); // OK
set<MyType> my_set(compareMyType); // ERROR

Почему это требуется? Почему тип функции компаратора не может быть определен типом клавиши?

Ответы [ 3 ]

4 голосов
/ 30 сентября 2019

В отличие от функций, для шаблонов классов нет частичного вычета. Если вы предоставляете параметры шаблона для шаблона класса, вам необходимо указать все не стандартные параметры, а в случае set вам необходимо указать тип сравнения, поскольку по умолчанию он равен std::less<T>, к которому указатель вашей функции не может быть преобразован в.

Было предложение получить частичное удержание, но оно было отклонено, и единственное, что сейчас добавлено в CTAD, - это то, что он будет работать через псевдоним.

2 голосов
/ 30 сентября 2019

На ваш вопрос ответили, так что это всего лишь вводная информация о том, как вы могли бы обойти эту проблему:

Вы можете указать operator< для своего типа, чтобы избежать необходимости использовать для него меньше функтора каждый раз, когда выиспользуйте его в set.

#include <iostream>
#include <set>

struct MyType {
    int value;
};

// added operator<
bool operator<(const MyType& l, const MyType& r) {
    return l.value < r.value;
}

int main() {
    std::set<MyType> my_set = {{3}, {2}, {1}};
    for(const MyType& m : my_set) 
        std::cout << ' ' << m.value;
    std::cout << "\n";
}

Вывод:

 1 2 3

Если вы хотите использовать его с контейнерами на основе хеша (например, unordered_set), вы можете аналогичным образом добавитьstd::hash<MyType> класс, который будет использоваться по умолчанию для вашего типа.

1 голос
/ 30 сентября 2019

Поскольку компаратор не обязательно является функцией (даже указатель на функцию). Фактически, значение по умолчанию для этого параметра - std::less<Key>, которое является шаблоном класса с operator(). Но вы можете передать тип чего-либо, что можно вызвать с двумя MyType const& и вернуть bool, следовательно, необходимо указать, что на самом деле означает .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...