TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #848 3.7K
Spaceship оператор. Детали 1
#новичкам

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

Ну для начала: наличие определенного spaceship оператора гарантирует вам наличие всех 6 операций сравнения:

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

// Spaceship operator (генерирует все 6 операторов сравнения)
auto operator<=>(const Time& other) const = default;
};

Time t1{10, 30, 15}; // 10:30:15
Time t2{9, 45, 30}; // 09:45:30
Time t3{10, 30, 15}; // 10:30:15

assert(t1 > t2); // 10:30:15 > 09:45:30
assert(!(t1 < t2)); // 10:30:15 не < 09:45:30
assert(t1 == t3); // 10:30:15 == 10:30:15
assert(t1 != t2); // 10:30:15 != 09:45:30
assert(t1 <= t3); // 10:30:15 <= 10:30:15
assert(t1 >= t2); // 10:30:15 >= 09:45:30


Это уже прекрасно, но это еще не все!

Обратите внимание на сигнатуру spaceship operator. Зачем там нужен auto?

Вот теперь объясненяем, почему это называется оператор трехстороннего сравнения.

Он возвращает объект, который содержит информацию о результате сравнения:

Time t1{10, 30, 15};  // 10:30:15
Time t2{9, 45, 30}; // 09:45:30

// Можно использовать и сам spaceship operator напрямую
auto cmp = t1 <=> t2;
if (cmp > 0) {
std::cout << "t1 is later than t2\n";
} else if (cmp < 0) {
std::cout << "t1 is earlier than t2\n";
} else {
std::cout << "t1 is the same as t2\n";
}
// OUTPUT:
// t1 is later than t2


Если результат сравнения >0, то первый операнд больше второго. И так далее по аналогии.

Тип возвращаемого значения у оператора один из этих трех:
- std::strong_ordering
- std::weak_ordering
- std::partial_ordering

Что они значат - тема отдельного разговора, но каждый из них может находится в одном из 3-х состояний: less, greater, equal. Это можно использовать, например, для проверки возвращаемых значений системных вызовов:

constexpr int strong_ordering_to_int(const std::strong_ordering& o)
{
if (o == std::strong_ordering::less) return -1;
if (o == std::strong_ordering::greater) return 1;
return 0;
}

char buffer[256];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));

// Сравниваем результат read() с нулём через <=>
switch (strong_ordering_to_int(bytes_read <=> 0)) {
case 1:
std::cout << "Read " << bytes_read << " bytes: "
<< std::string(buffer, bytes_read) << "\n";
break;
case 0:
std::cout << "End of file reached (0 bytes read)\n";
break;
case -1:
perror("read failed");
return 1;
}


Кейсы применения непосредственно spaceship'а в коде не так обширны, потому что не очень привычно, есть вопросы к перфу(об этом в следующем посте) да и поди разберись с этими ордерингами еще. Но его точно стоит использовать для автоматической генерации 6 базовых операторов.

Be universal. Stay cool.

#cppcore #cpp20
  • ❤ 33
  • 👍 15
  • 🔥 10
  • ⚡ 1
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 →