次のコードは、c ++ 17モードではclang-trunkで正常にコンパイルされますが、c ++ 2a(今後の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{});
}
また、gcc-trunkまたはclang-9.0.0でも問題なくコンパイルできます。https://godbolt.org/z/8GGT78
clang-trunkおよび-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)
C ++ 20はオーバーロードのみを可能にしoperator==
、コンパイラはoperator!=
の結果を否定することによって自動的に生成することを理解していoperator==
ます。私が理解している限り、これは戻り値の型がである場合にのみ機能しbool
ます。
問題の原因は、固有に、我々は、オペレータのセットを宣言することで==
、!=
、<
の間、... Array
オブジェクト又はArray
およびスカラー、リターン(の発現)のアレイbool
次いで要素ごとにアクセスすること、またはそうでなければ使用することができます( )。例えば、
#include <Eigen/Core>
int main()
{
Eigen::ArrayXd a(10);
a.setRandom();
return (a != 0.0).any();
}
上記の私の例とは対照的に、これはgcc-trunk:https ://godbolt.org/z/RWktKsでも失敗します。これを非Eigenの例にまだ削減できていません。これは、clang-trunkとgcc-trunkの両方で失敗します(上の例はかなり単純化されています)。
関連問題レポート:https : //gitlab.com/libeigen/eigen/issues/1833
私の実際の質問:これは実際にはC ++ 20の重大な変更ですか(そして比較演算子をオーバーロードしてメタオブジェクトを返す可能性がありますか)、それともclang / gccの回帰の可能性が高いですか?