概念 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
必须是布尔值。但也有类型应提供的语义要求。
可以如下定义 t1
和 t2
之间的相等性。如果它们相等,那么对于作用于 T
的任何(纯)函数 f
,f(t1) == f(t2)
.
但是对于 between 类型的相等性,这个定义在概念上是不够的。毕竟,采用 T
的函数 f
可能不会采用 U
.
为了处理这个事实,C++20 根据假设的第三种类型 C
定义了 T
和 U
之间的相等性。 C
可以是 T
、U
或其他实际类型。但 C++20 非对称相等性的主要要求是存在一种类型 C
(允许对称相等性测试),可以隐式转换对 T
和 U
的引用。这是 common_reference
类型。
这允许标准根据 C
定义不对称相等。也就是说,对于任何接受 C
的函数 f
,如果 t == u
,则 f(t) == f(u)
。
考虑 string
和 string_view
。 string
可以隐式转换为 string_view
。因此,在进行非对称比较时,比较在概念上表现得 就好像 在进行比较之前将任何 string
转换为 string_view
。也就是说,string_view
充当类型 C
.
此条款专门用于阻止您尝试编写的表单代码。从概念上讲,您的结构 A
与 string_view
没有等价关系。采用 string_view
的函数根本无法采用等值的 A
,即使 string_view
是它们之间的共同引用。
我正在尝试在编译时测试两种类型是否具有相等可比性,并且我已经为它们定义了 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
必须是布尔值。但也有类型应提供的语义要求。
可以如下定义 t1
和 t2
之间的相等性。如果它们相等,那么对于作用于 T
的任何(纯)函数 f
,f(t1) == f(t2)
.
但是对于 between 类型的相等性,这个定义在概念上是不够的。毕竟,采用 T
的函数 f
可能不会采用 U
.
为了处理这个事实,C++20 根据假设的第三种类型 C
定义了 T
和 U
之间的相等性。 C
可以是 T
、U
或其他实际类型。但 C++20 非对称相等性的主要要求是存在一种类型 C
(允许对称相等性测试),可以隐式转换对 T
和 U
的引用。这是 common_reference
类型。
这允许标准根据 C
定义不对称相等。也就是说,对于任何接受 C
的函数 f
,如果 t == u
,则 f(t) == f(u)
。
考虑 string
和 string_view
。 string
可以隐式转换为 string_view
。因此,在进行非对称比较时,比较在概念上表现得 就好像 在进行比较之前将任何 string
转换为 string_view
。也就是说,string_view
充当类型 C
.
此条款专门用于阻止您尝试编写的表单代码。从概念上讲,您的结构 A
与 string_view
没有等价关系。采用 string_view
的函数根本无法采用等值的 A
,即使 string_view
是它们之间的共同引用。