O código a seguir é compilado com clang-trunk no modo c ++ 17, mas é interrompido no modo c ++ 2a (próximo c ++ 20):
// Meta struct describing the result of a comparison
struct Meta {};
struct Foo {
Meta operator==(const Foo&) {return Meta{};}
Meta operator!=(const Foo&) {return Meta{};}
};
int main()
{
Meta res = (Foo{} != Foo{});
}
Também compila bem com gcc-trunk ou clang-9.0.0: https://godbolt.org/z/8GGT78
O erro com clang-trunk e -std=c++2a
:
<source>:12:19: error: use of overloaded operator '!=' is ambiguous (with operand types 'Foo' and 'Foo')
Meta res = (f != g);
~ ^ ~
<source>:6:10: note: candidate function
Meta operator!=(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function
Meta operator==(const Foo&) {return Meta{};}
^
<source>:5:10: note: candidate function (with reversed parameter order)
Eu entendo que o C ++ 20 tornará possível apenas sobrecarregar operator==
e o compilador será gerado automaticamente operator!=
negando o resultado de operator==
. Tanto quanto eu entendo, isso só funciona enquanto o tipo de retorno é bool
.
A fonte do problema é que em Eigen que declarar um conjunto de operadores ==
, !=
, <
, ... entre Array
objectos ou Array
e escalares, que retornam (uma expressão de) uma matriz de bool
(a qual pode então ser acedida elemento a elemento, ou de outro modo utilizados ) Por exemplo,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
Em contraste com o meu exemplo acima, isso ainda falha com o gcc-trunk: https://godbolt.org/z/RWktKs . Ainda não consegui reduzir isso a um exemplo que não é Eigen, que falha nos clang-trunk e no gcc-trunk (o exemplo na parte superior é bastante simplificado).
Relatório de problema relacionado: https://gitlab.com/libeigen/eigen/issues/1833
Minha pergunta real: isso é realmente uma mudança de quebra no C ++ 20 (e existe a possibilidade de sobrecarregar os operadores de comparação para retornar Meta-objetos) ou é mais provável uma regressão no clang / gcc?