Il codice seguente viene compilato correttamente con clang-trunk in modalità c ++ 17 ma si interrompe in modalità c ++ 2a (imminente 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{});
}
Si compila anche bene con gcc-trunk o clang-9.0.0: https://godbolt.org/z/8GGT78
L'errore con 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)
Comprendo che C ++ 20 renderà possibile solo il sovraccarico operator==
e il compilatore genererà automaticamente operator!=
negando il risultato di operator==
. Per quanto ho capito, questo funziona solo finché è il tipo restituito bool
.
La fonte del problema è che in Eigen si dichiara un insieme di operatori ==
, !=
, <
, ... tra Array
oggetti o Array
e scalari, che di ritorno (espressione di) un array bool
(che può quindi accedere elemento-saggio, o altrimenti utilizzato ). Per esempio,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
Contrariamente al mio esempio sopra, questo non riesce nemmeno con gcc-trunk: https://godbolt.org/z/RWktKs . Non sono ancora riuscito a ridurlo a un esempio non Eigen, che fallisce sia in clang-trunk che in gcc-trunk (l'esempio in alto è abbastanza semplificato).
Rapporto sui problemi correlati: https://gitlab.com/libeigen/eigen/issues/1833
La mia vera domanda: si tratta in realtà di un cambiamento sostanziale in C ++ 20 (ed esiste la possibilità di sovraccaricare gli operatori di confronto per restituire Meta-oggetti) o è più probabile una regressione in clang / gcc?