Инициализация multiset с помощью пользовательской функции сравнения в C++
рассмотрим следующую функцию сравнения:
bool compare(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs){
return lhs->value < rhs->value;
}
Теперь идея состоит в том, чтобы инициализировать multiset типа std::shared_ptr<myObject>
который приказывает элементы с вышеуказанной функцией. Поэтому из книги, которую я читал, это должно быть сделано так:
std::multiset<std::shared_ptr<myObject>, decltype(compare)*> myset{compare};
вопрос:
мой вопрос в том, что в объявлении я понимаю, что указатель функции передается для ссылки на функцию сравнения, но почему мы инициализируем набор wtih {compare}?? в чем его важность и почему обязательно так поступать??
4 ответов
потому что набор нужен функтор сравнения для работы. Если вы не укажете его,он будет создан по умолчанию. В этом случае, поскольку вы используете тип function-pointer, построенный по умолчанию, будет нулевым указателем, который нельзя вызвать; поэтому вместо этого вы должны предоставить правильный указатель функции во время выполнения.
лучшим подходом может быть использование типа класса функций (a.к. a. functor type); затем вызов функции может быть разрешен во время компиляции и объект, построенный по умолчанию, будет поступать правильно:
struct compare {
bool operator()(std::shared_ptr<myObject> &lhs,
std::shared_ptr<myObject> &rhs) const {
return lhs->value < rhs->value;
}
};
std::multiset<std::shared_ptr<myObject>, compare> myset;
компаратор, переданный шаблону, должен быть типом чего-то, что можно вызвать с помощью оператора вызова функции. Это будет либо класс, который перегрузил этот оператор, либо тип лямбды или указателя функции. В cunstrutor set должен быть передан экземпляр этого типа. Так что decltype(compare)*
- тип указателя функции и &compare
- это указатель на функцию.
decltype(compare)*
в параметре template указывает тип компаратора. Он не говорит , который функция должна использоваться-является ли это compare
, foo
, bar
или что-то еще. Следовательно, параметр конструктора.
чтобы получить доступ к вашим элементам, вам нужно предоставить функцию для строгий слабый заказ для вашего типа.
std::multiset
есть следующий конструктор:
explicit multiset (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
как вы можете видеть, вы можете сделать это путем передачи comp
указатель функции (или объект функции) на конструктор.