El siguiente código se compila bien con clang-trunk en el modo c ++ 17 pero se rompe en el 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{});
}
También se compila bien con gcc-trunk o clang-9.0.0: https://godbolt.org/z/8GGT78
El error con clang-trunk y -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)
Entiendo que C ++ 20 hará posible solo sobrecargar operator==
y el compilador generará automáticamente operator!=
al negar el resultado de operator==
. Por lo que yo entiendo, esto solo funciona mientras el tipo de retorno sea bool
.
La fuente del problema es que en Eigen declaramos un conjunto de operadores ==
, !=
, <
, ... entre Array
objetos o Array
y escalares, que devuelven (una expresión de) una matriz de bool
(que luego se puede acceder elemento a elemento, o utilizado de otra manera ) P.ej,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
En contraste con mi ejemplo anterior, esto incluso falla con gcc-trunk: https://godbolt.org/z/RWktKs . Todavía no he logrado reducir esto a un ejemplo que no sea Eigen, que falla tanto en clang-trunk como en gcc-trunk (el ejemplo en la parte superior está bastante simplificado).
Informe de problema relacionado: https://gitlab.com/libeigen/eigen/issues/1833
Mi pregunta real: ¿es esto realmente un cambio radical en C ++ 20 (y existe la posibilidad de sobrecargar los operadores de comparación para devolver Metaobjetos), o es más probable una regresión en clang / gcc?