Como o compilador C++20 pode gerar operadores de comparação padrão para uma classe, inclusive como função não-membro amigo, consulte (2) em cppreference.com .
Me deparei com o código trabalhando no MSVC que faz isso para uma classe local dentro de uma função:
void foo() {
struct A;
bool operator ==(const A&, const A&);
struct A {
friend bool operator ==(const A&, const A&) = default;
};
}
Infelizmente, não funciona no Clang ou no GCC, que reclama:
error: cannot define friend function 'operator==' in a local class definition
Demonstração online: https://godbolt.org/z/Ts1fer1d1
Existe uma maneira de tornar o código aceito pelo GCC:
void foo() {
struct A;
bool operator ==(const A&, const A&);
struct A {
friend bool operator ==(const A&, const A&);
};
bool operator ==(const A&, const A&) = default;
}
que agora apenas imprime algum aviso vago:
warning: declaration of 'bool operator==(const foo()::A&, const foo()::A&)' has 'extern' and is initialized
mas os outros dois compiladores não gostam, demonstração online: https://godbolt.org/z/he1zjj46G
Enquanto os compiladores divergem, qual deles está correto em ambos os exemplos acima?
A norma é bem clara quanto a isso:
- [class.friend] p6
Seu primeiro exemplo de código está definindo a
friend
em uma classe local, portanto, ele viola este parágrafo.O segundo exemplo define uma função no escopo do bloco, que também é claramente malformada:
- [dcl.fct.def.general] p2
O fato de o GCC compilar é um bug do compilador e possivelmente relacionado ao fato de o GCC oferecer suporte a funções locais como uma extensão do compilador. O aviso
has 'extern' and is initialized
que ele dá não faz sentido e normalmente ocorreria em cenários como:Observação: enviei um relatório de bug para este problema: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111079