当用非布尔返回值重载相等比较时,C ++ 20中发生重大更改或clang-trunk / gcc-trunk中的回归?

问题描述 投票:2回答:1

以下代码在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中,我们在==对象或!=与标量之间声明了一组运算符<ArrayArray,...,它们返回( )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 ...

language-lawyer eigen eigen3 c++20
1个回答
1
投票

[over.match.best] / 2列出了如何优先考虑集合中的有效重载。 2.8节告诉我们F1F2好,如果(在[[许多

© www.soinside.com 2019 - 2024. All rights reserved.