概念 std::equality_comparable_with 不适用于用户定义的相等运算符

concept std::equality_comparable_with not working for user-defined equality operator

我正在尝试在编译时测试两种类型是否具有相等可比性,并且我已经为它们定义了 operator==,所以它们应该是。然而,以下代码无法编译:

#include <string_view>

struct A { int n; };
bool operator==(const A& a, const std::string_view s) { return a.n == s.size(); }

static_assert(std::equality_comparable_with<A, std::string_view>);

(godbolt) 我什至尝试过为相反的顺序定义 operator==,并为 A 本身定义,但它也不起作用。

当然,像下面这样的东西就可以了

static_assert(std::equality_comparable_with<std::string, std::string_view>);

我在这里错过了什么?

平等不仅仅意味着 operator== 有效且 returns 正确。以及标准库概念 require this.

equality_comparable defines symmetric comparison(同类比较相等)。就语法而言,这意味着 t1==t2 必须是布尔值。但也有类型应提供的语义要求。

可以如下定义 t1t2 之间的相等性。如果它们相等,那么对于作用于 T 的任何(纯)函数 ff(t1) == f(t2).

但是对于 between 类型的相等性,这个定义在概念上是不够的。毕竟,采用 T 的函数 f 可能不会采用 U.

为了处理这个事实,C++20 根据假设的第三种类型 C 定义了 TU 之间的相等性。 C 可以是 TU 或其他实际类型。但 C++20 非对称相等性的主要要求是存在一种类型 C(允许对称相等性测试),可以隐式转换对 TU 的引用。这是 common_reference 类型。

这允许标准根据 C 定义不对称相等。也就是说,对于任何接受 C 的函数 f,如果 t == u,则 f(t) == f(u)

考虑 stringstring_viewstring 可以隐式转换为 string_view。因此,在进行非对称比较时,比较在概念上表现得 就好像 在进行比较之前将任何 string 转换为 string_view。也就是说,string_view 充当类型 C.

此条款专门用于阻止您尝试编写的表单代码。从概念上讲,您的结构 Astring_view 没有等价关系。采用 string_view 的函数根本无法采用等值的 A,即使 string_view 是它们之间的共同引用。