Я пытаюсь понять новые операторы сравнения по умолчанию, представленные в С++ 20. Моя проблема связана с тем, что оператор сравнения с явным значением по умолчанию определяется неявно. Следующий пример кода иллюстрирует вопрос:
#include <iostream>
struct B
{
operator bool() const { return true; }
};
struct D : B
{
bool operator==(const D&) const = default;
};
bool operator==(B, B) { return false; }
int main ()
{ D d;
std::cout << (d == d);
}
/* Outputs:
0 in gcc 10.1
1 in msvc 19.26
*/
Вывод этой программы зависит от компилятора. Кажется, что MSVC определяет оператор == для класса D, когда он сталкивается с объявлением по умолчанию, поэтому он не использует оператор ==, который определен позже для класса B. Напротив, gcc ожидает с неявным определением D. operator== до тех пор, пока он действительно не понадобится, и к этому времени оператор ==, определенный для B, находится в области видимости и используется. Какое поведение является правильным?
Связанный с этим вопрос: почему оператор == по умолчанию не может быть объявлен для класса со ссылочными членами? Я мог видеть, что ссылочные члены могут создавать проблемы с подходом MSVC, потому что ссылочные члены могут ссылаться на неполный тип, когда встречается объявление по умолчанию для operator==. При подходе gcc тип ссылки всегда будет полным до того, как gcc попытается определить оператор по умолчанию.