Причина, по которой они только переопределяют <
, заключается в том, что по умолчанию это то, что заказанные контейнеры используют для сравнения значений, так что это все, что им нужно определить для ответа на вопрос.
#include <set>
struct my_fancy_integer
{
int fancy;
};
// This is all std::set (or any ordered container) needs by default,
// So for an example answer I won't do anything else (as I expect you to
// learn and understand *why* it needs this by default).
bool operator<(const my_fancy_integer& first, const my_fancy_integer& second)
{
return first.fancy < second.fancy;
}
// But I should really also defined the other comparison operators...
// For example, without operator> defined this would fail:
//
// std::set<my_fancy_integer, std::greater<my_fancy_integer>> x;
//
// But since you read documentation for std::set and std::greater you
// understand why this fails: std::set will use std::greater to order
// the values, and std::greater (by default) will try to use operator>.
int main()
{
std::set<my_fancy_integer> x; // okay
}
Нет, другие операторы неявно определяются в терминах (ни в терминах чего-либо еще). В реальном приложении, если вы определили один, вы должны определить их все.
В качестве альтернативы, если <
не имеет смысла для вашего типа синтаксически, но упорядочение их по-прежнему ценно, определите используемый предикат по умолчанию, который пользователи должны передать аргументу шаблона предиката заданного контейнера.
#include <set>
#include <string>
#include <tuple>
struct my_employee
{
std::string name;
int salary;
int yearsEmployed;
};
// Saying one employee is "less" than another doesn't really make sense...
// But I can still give an *ordering* on them:
struct my_employee_ordering
{
bool operator()(const my_employee& first, const my_employee& second) const
{
// I'll just reuse std::tuple's comparison operator, and tie the
// fields of each structure into a tuple to use it. This orders
// by name, salary, then yearsEmployed.
return std::tie(first.name, first.salary, first.yearsEmployed) <
std::tie(second.name, second.salary, second.yearsEmployed);
}
};
int main()
{
// We need to tell std::set how to order employees:
std::set<my_employee, my_employee_ordering> x; // okay
}
operator()
является оператором вызова функции. Это позволяет ваш объект быть «под названием»:
struct foo
{
void operator()(int x) { std::cout << x << std::endl; }
};
foo f;
f(5); // calls foo::operator()(5)
'operator()' позволяет сортировать по другим критериям, чем метод 'operator <' объекта по умолчанию. Например, полку книг можно заказать по названию, автору или десятичному числу Дьюи. Класс book не может иметь 3 '' '' '' функции '' функции. Таким образом, функция записывается для сравнения двух книг автора или другой функции, написанной для сравнения с системой Dewey Decimal. –
В будущем, пожалуйста, не задавайте сразу два вопроса. Либо спросите, не определены ли операторы в терминах друг друга, либо спросите, что такое 'operator()'. Отдельные, они, вероятно, очень доступны для поиска. – GManNickG
В дополнение к уже указанным ответам найдите 'std :: rel_ops'. –