以下代码在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==
。据我了解,这仅在return类型为时才有效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。我还没有设法将其简化为非本征示例,这在clang-trunk和gcc-trunk中均失败(顶部的示例已相当简化)。
相关问题报告:https://gitlab.com/libeigen/eigen/issues/1833
我的实际问题:这实际上是C ++ 20中的重大变化(是否有可能使比较运算符过载以返回元对象),还是更有可能在clang / gcc中回归?