将三路比较运算符的结果与nullptr进行比较有什么作用?

What does comparing the result of the three-way comparison operator with nullptr do?

鉴于cppreference on <=>中的示例,我们可以将示例代码简化为:

struct person {
    std::string name;
    std::string surname;

    auto operator <=> (const person& p) const {
        if (const auto result = name <=> p.name; result != 0) {
            return result;
        } else {
            return surname <=> p.surname;
        }
    }
};

但是我的 IDE (CLion 2020.2) 通过 clang-tidy 警告说 result != 0 实际上应该是 result != nullptr。我不知道我们可以比较 std::###_orderingnullptr。 Cprefence 也 claims that we should rather compare it with literal 0nullptr 那里什么都没有。

此代码:

int main() {
    person p1{"ccc", "vvv"};
    person p2{"aaa", "zzz"};

    std::cout << (p1 < p2);
}

编译(GCC 10.1.0,Rev3,由 MSYS2 项目构建)并产生与 0nullptr 版本相同的结果。


然而,我的 IDE 也警告我应该“Clang-Tidy:使用 nullptr” 和 p1 < p2。通过应用“修复”,代码更改为 std::cout << (p1 nullptr p2);,但无法编译。它暗示它可能是 clang-tidy 中的一个错误,但它并没有解释为什么我们可以将顺序与 nullptr 进行比较。为什么我们可以,为什么它有效,为什么我们想要它?

But my IDE (CLion 2020.2), via clang-tidy, warns that result != 0 should actually be result != nullptr.

这是错误的。应该是result != 0。比较类别指定为仅可与 文字 0.

进行比较

检查可能来自这样一个事实,即在 C++20 中实现与文字 0 进行比较的唯一真正方法是采用类型为某个未指定指针或指向指向的函数指针的参数成员 - 并且 clang-tidy 可能会将您作为指针参数提供的任何 0 标记为 应该 nullptr。大多数时候,这是正确的。只是不专门在这里。事实上,如果你写 result != nullptr 它可能会编译 - 但那是错误的,你不应该这样做。

这是一个clang-tidy问题,需要理解的是,对于比较类别,不应该这样标记文字0的使用。