В чем цимес. Лично мне в С++ не всегда понятно, что должно быть "нормальным поведением по-умолчанию", а что "нужно прописать явно".
Давайте посмотрим вот сюда:
#include <iostream>
struct Good {
int i;
bool operator==(const Good&) const = default;
};
int main() {
Good good1{1}, good2{2};
std::cout << (good1 == good2) << std::endl;
return 0;
}
Мы создали структуру, прописали, что ее можно сравнивать (по дефолту), и сравнили.
А теперь давайте унаследуем такую же структуру от пустой структуры
#include <iostream>
struct Empty {
// bool operator==(const Empty&) const = default;
};
struct Bad : Empty {
int i;
bool operator==(const Bad&) const = default;
/* error:
constexpr bool Bad::operator==(const Bad&) const'
is implicitly deleted because the default
definition would be ill-formed
*/
};
static_assert(sizeof(Good) == sizeof(Bad));
int main() {
Bad bad1{{}, 1}, bad2{{}, 2};
std::cout << (bad1 == bad2) << std::endl;
return 0;
}
Мы не можем скомпилировать этот код, потому что оператор сравнения "по-умолчанию" не создается, пока мы не объявим явным образом оператор сравнения для пустой структуры.
Другими словами, нам надо явно писать что-то такое:
struct Empty {
bool operator==(const Empty&) const {
return true;
}
};
И вот не понятно, толи все логично, и я придераюсь. Толи правда неплохо бы генерировать операторы сравнения для пустых структур, а явно прописовать требовать только когда мы хотим их явно запретить. Я не знаю, я не понимаю...