Я использую структуры данных, и я много сортирую эти структуры данных. Эти структуры данных содержат указатели на объекты, а не непосредственно на сами объекты. Теперь я могу написать простой функтор сравнения или функцию, чтобы сообщить алгоритму сортировки, как сортировать указатели:
struct Object_ptr_comparer {
bool operator()(const Object* first, const Object* second) {
return *first < *second;
}
};
И использовать например std::sort
:
Object_ptr_comparer comp;
std::sort(data_str.begin(), data_str.end(), comp);
Единственная проблема с этим решением, что я должен написать дополнительный функтор компаратора указателя для любого типа класса. Да, я мог бы использовать наследование и полиморфизм, чтобы написать только компаратор некоторого корневого класса, но я не хочу. Есть ли другой умный способ сделать это?
Вот для чего нужны шаблоны!
struct ptr_comparer {
template<class Object>
bool operator()(const Object* first, const Object* second) const {
return std::less<Object>()(*first, *second);
}
};
std::sort(data_str.begin(), data_str.end(), ptr_comparer());
Поскольку я шаблонизировал оператор, а не специализировал компаратор напрямую, компилятор может определять типы, поэтому нам не нужно помещать типы напрямую.
я использую std::less
скорее, чем operator<
потому что он безопасно сравнивает указатели с указателями (например, char**
), а не полагаться на неопределенное поведение. std::less
отступает на operator<
, так что это не добавляет сложности при вызове кода, и не должно быть недостатков.
Как насчет шаблона?
struct ptr_comparer {
template<typename T>
bool operator()(const T* first, const T* second) {
return *first < *second;
}
};
используется так:
std::sort(data_str.begin(), data_str.end(), ptr_comparer());