-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Open
Labels
clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerNew/improved warning or error message in Clang, but not in clang-tidy or static analyzer
Description
When defining a struct that provides at least ==
and <
operators but not a three-way comparison operator, and using auto operator<=>(T const&) = default;
in another struct, Clang emits an error indicating that the defaulted operator<=> is implicitly deleted.
<source>:15:12: error: object of type 'Item' cannot be compared because its 'operator<=>' is implicitly deleted
15 | Item{} < Item{};
| ^
<source>:11:10: note: explicitly defaulted function was implicitly deleted here
11 | auto operator<=>(const Item &other) const = default;
| ^
<source>:9:7: note: defaulted 'operator<=>' is implicitly deleted because there is no viable three-way comparison function for member 'text'
9 | A text;
| ^
This message is unclear for users who have correctly implemented ==
and <
. GCC, in comparison, provides a much more helpful message suggesting to change the return type from auto
to a comparison category type to allow the comparison to use operator<
and operator==
:
<source>:11:10: note: changing the return type from 'auto' to a comparison category type will allow the comparison to use 'operator<' and 'operator=='
11 | auto operator<=>(const Item &other) const = default;
| ^~~~~~~~
Desired Behavior
- Suggest, as GCC does, that changing the return type from
auto
to a comparison category type (e.g.,std::strong_ordering
orstd::partial_ordering
) would allowoperator<=>
to fall back onoperator<
andoperator==
.
Environment
- Clang version: 17, 18, 19, 20
Code to reproduce
https://godbolt.org/z/6hzfPc7er
#include <compare>
struct A {};
bool operator==(A const&, A const&);
bool operator<(A const&, A const&);
struct Item {
A text;
auto operator<=>(const Item &other) const = default;
};
int main() {
Item{} < Item{};
}
Full Clang Output
<source>:11:10: warning: explicitly defaulted three-way comparison operator is implicitly deleted [-Wdefaulted-function-deleted]
11 | auto operator<=>(const Item &other) const = default;
| ^
<source>:9:7: note: defaulted 'operator<=>' is implicitly deleted because there is no viable three-way comparison function for member 'text'
9 | A text;
| ^
<source>:11:49: note: replace 'default' with 'delete'
11 | auto operator<=>(const Item &other) const = default;
| ^~~~~~~
| delete
<source>:15:12: error: object of type 'Item' cannot be compared because its 'operator<=>' is implicitly deleted
15 | Item{} < Item{};
| ^
<source>:11:10: note: explicitly defaulted function was implicitly deleted here
11 | auto operator<=>(const Item &other) const = default;
| ^
<source>:9:7: note: defaulted 'operator<=>' is implicitly deleted because there is no viable three-way comparison function for member 'text'
9 | A text;
| ^
Full Gcc Output
<source>:15:19: error: use of deleted function 'constexpr auto Item::operator<=>(const Item&) const'
15 | Item{} < Item{};
| ^
<source>:11:10: note: 'constexpr auto Item::operator<=>(const Item&) const' is implicitly deleted because the default definition would be ill-formed:
11 | auto operator<=>(const Item &other) const = default;
| ^~~~~~~~
<source>:9:7: error: no match for 'operator<=>' (operand types are 'A' and 'A')
9 | A text;
| ^~~~
<source>:11:10: note: changing the return type from 'auto' to a comparison category type will allow the comparison to use 'operator<' and 'operator=='
11 | auto operator<=>(const Item &other) const = default;
| ^~~~~~~~
Metadata
Metadata
Assignees
Labels
clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerNew/improved warning or error message in Clang, but not in clang-tidy or static analyzer