以下代码在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
的情况下有效。
问题的根源在于,在Eigen中,我们在==
对象或!=
与标量之间声明了一组运算符<
,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中的回归?
以下代码在c ++ 17模式下使用clang-trunk可以正常编译,但是在c ++ 2a(即将到来的c ++ 20)模式下可以中断://描述比较结构Meta的结果的元结构struct Meta {}; struct Foo {Meta ...
[over.match.best] / 2列出了如何优先考虑集合中的有效重载。 2.8节告诉我们F1
比F2
好,如果(在[[许多