Given the example from cppreference on <=>
, we can simplify the example code to:
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;
}
}
};
But my IDE (CLion 2020.2), via clang-tidy, warns that result != 0
should actually be result != nullptr
. I didn't know that we can compare std::###_ordering
with nullptr
. Cpprefence also claims that we should rather compare it with literal 0
. There is nothing about nullptr
there.
This code:
int main() {
person p1{"ccc", "vvv"};
person p2{"aaa", "zzz"};
std::cout << (p1 < p2);
}
compiles (GCC 10.1.0, Rev3, Built by MSYS2 project) and yields identical results to both the 0
and the nullptr
version.
However, my IDE also warns me that I should "Clang-Tidy: Use nullptr" with p1 < p2
. By applying the "fix", the code changes to std::cout << (p1 nullptr p2);
which, well, doesn't compile. It hints that it may be a bug in clang-tidy, but it doesn't explain why we can compare the orderings with nullptr
. Why we can, why does it work and why would we want that?
But my IDE (CLion 2020.2), via clang-tidy, warns that
result != 0
should actually beresult != nullptr
.
This is wrong. It should be result != 0
. The comparison categories are specified to only be comparable against the literal 0
.
The check likely comes from the fact that the only real way to implement comparing against the literal 0
in C++20 is to take an argument whose type is some unspecified pointer or function pointer to pointer to member - and clang-tidy likely flags any 0
that you provide as an argument to a pointer as something that should be nullptr
. Most of the time, this is correct. Just not specifically here. And indeed, if you write result != nullptr
it probably will compile - but that's wrong and you should not do it.
This is a clang-tidy problem, it needs to understand that for comparison categories, it should not flag the use of literal 0 in this way.