Le code suivant compile correctement avec clang-trunk en mode c ++ 17 mais se casse en mode c ++ 2a (c ++ 20 à venir):
// 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{});
}
Il compile également très bien avec gcc-trunk ou clang-9.0.0: https://godbolt.org/z/8GGT78
L'erreur avec clang-trunk et -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)
Je comprends que C ++ 20 ne permettra que de surcharger operator==
et que le compilateur générera automatiquement operator!=
en annulant le résultat de operator==
. Pour autant que je comprends, cela ne fonctionne que tant que le type de retour est bool
.
La source du problème est que nous déclarons Eigen un ensemble d'opérateurs ==
, !=
, <
, ... entre Array
objets ou Array
et Scalaires, qui reviennent (une expression de) un tableau de bool
(qui peut alors être accessible élément par élément, ou utilisé autrement ). Par exemple,
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
Contrairement à mon exemple ci-dessus, cela échoue même avec gcc-trunk: https://godbolt.org/z/RWktKs . Je n'ai pas encore réussi à réduire cela à un exemple non-Eigen, qui échoue à la fois dans clang-trunk et gcc-trunk (l'exemple en haut est assez simplifié).
Rapport de problème connexe: https://gitlab.com/libeigen/eigen/issues/1833
Ma vraie question: est-ce en fait un changement de rupture en C ++ 20 (et y a-t-il une possibilité de surcharger les opérateurs de comparaison pour renvoyer des méta-objets), ou est-ce plus probablement une régression dans clang / gcc?