オーバーライドするだけの理由<
は、順序付けられたコンテナーが値を比較するためにデフォルトで使用するものであるため、質問に答えるために定義する必要があるのはそれだけだからです。
#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
}
いいえ、他の演算子はそれに関して暗黙的に定義されていません (または他のものに関しても)。実際のアプリケーションでは、1 つを定義したら、それらすべてを定義する必要があります。
または、<
構文的に意味をなさないが順序付けが重要な場合は、ユーザーが順序付けられたコンテナの述語テンプレート引数に渡す必要がある使用可能なデフォルト述語を定義します。
#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)