【问题标题】:concept std::equality_comparable_with not working for user-defined equality operator概念 std::equality_comparable_with 不适用于用户定义的相等运算符
【发布时间】:2022-01-11 04:09:39
【问题描述】:

我试图在编译时测试两种类型是否可以相等,并且我已经为它们定义了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>);

我在这里错过了什么?

【问题讨论】:

    标签: c++ operator-overloading c++20 c++-concepts


    【解决方案1】:

    平等不仅仅意味着operator== 是有效的并且返回true。以及标准库概念require this

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

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

    但是对于 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 是它们之间的公共引用。

    【讨论】:

    • 纯函数的相等定义在实践中不是很有帮助:考虑auto f(const std::vector&lt;int&gt; &amp;v) {return v.capacity();}
    猜你喜欢
    • 2022-09-23
    • 1970-01-01
    • 2022-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 2023-03-21
    • 2019-10-03
    相关资源
    最近更新 更多