TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #846 4.5K
​​Оператор, бороздящий просторы вселенной
#новичкам

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

struct Time {
int hours;
int minutes;
int seconds;

bool operator<(const Time& other) {
return std::tie(hours, minutes, seconds) < std::tie(other.hours, other.minutes, other.seconds);
}
};


Однако иногда структуры требуется сравнивать и с помощью других операторов: >, ==, !=, >=, <=. В итоге полноценный набор операторов сравнения для Time выглядит так:

struct Time {
int hours;
int minutes;
int seconds;

bool operator<(const Time& other) const noexcept {
return std::tie(hours, minutes, seconds) < std::tie(other.hours, other.minutes, other.seconds);
}

bool operator==(const Time& other) const noexcept {
return std::tie(hours, minutes, seconds) == std::tie(other.hours, other.minutes, other.seconds);
}

bool operator<=(const Time& other) const noexcept { return !(other < *this); }
bool operator>(const Time& other) const noexcept { return other < *this; }
bool operator>=(const Time& other) const noexcept { return !(*this < other); }
bool operator!=(const Time& other) const noexcept { return !(*this == other); }
};


Попахивает зловонным бойлерплейтом.

Недавно увидел мем, где девочка 8-ми лет, которая изучает питон, спрашивает отца: "папа, а если компьютер знает, что здесь пропущено двоеточие, почему он сам не может его поставить?". И батя такой: "Я не знаю, дочка, я не знаю ...".

Здесь вот похожая ситуация. Компилятор же умеет сравнивать набор чисел в лексикографическом порядке. Какого хрена он не может сделать это за нас?

Начиная с С++20 может!

Теперь вы можете сказать компилятору, что вам достаточно простого лексикографического сравнения поле класса и пусть он сам его генерирует:

struct Time {
int hours;
int minutes;
int seconds;

bool operator<(const Time& other) const = default;
bool operator==(const Time& other) const = default;
bool operator<=(const Time& other) const = default;
bool operator>(const Time& other) const = default;
bool operator>=(const Time& other) const = default;
bool operator!=(const Time& other) const = default;
};


В отличие от специальных методов класса, компилятор не сгенерирует за нас эти операторы, если мы явно не попросим. Получается, что мы решили только полпроблемы и нам все равно нужно писать 6 скучных засоряющих код строчек. Хотелось бы один раз сказать, что нам нужны сразу все операторы.

Тут же нам на помощью приходит еще одна фича С++20 - трехсторонний оператор сравнения или spaceship operator. Теперь код выглядит так:

struct Time {
int hours;
int minutes;
int seconds;

// Один оператор вместо шести!
auto operator<=>(const Time& other) const = default;
};


Spaceship потому что похож на космический корабль, имхо прям имперский истребитель из далекой-далекой.

Один раз определив этот оператор можно сравнивать объекты какими угодно операторами и это будет работать. Подробнее про применение будет в следующем посте.

Conquer your space. Stay cool.

#cppcore #cpp20
  • ❤ 43
  • 👍 23
  • 🔥 12
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →