Description
[class.compare.default] p1 just says
A comparison operator function for class C that is defaulted on its first declaration and is not defined as deleted is implicitly defined when it is odr-used or needed for constant evaluation.
Consider this example
struct HasNoLessThan { };
struct C{
friend HasNoLessThan operator <=>(C const&, C const&);
bool operator <(C const&) const /*noexcept*/ = default;
};
int main(){
using ptr = decltype(&C::operator<); // #1
}
Since &C::operator<
appears as an unevaluated operand, function C::operator <
is not odr-used by this expression. However, Clang reports a diagnosis that:
in evaluation of exception specification for 'C::operator<' needed here
[except.spec] p11 says
The exception specification for a comparison operator function ([over.binary]) without a noexcept-specifier that is defaulted on its first declaration is potentially-throwing if and only if any expression in the implicit definition is potentially-throwing.
So, It is reasonable to check the definition of the defaulted function. However, we just define two contexts that can cause the implicit definition for the defaulted function. Checking the expressions in the implicit definition is not defined to be odr-used nor constant evaluation of the function. It seems that we lack the case that determines the exception specification of a defaulted comparison operator function.
Improvement:
A comparison operator function for class C that is defaulted on its first declaration and is not defined as deleted is implicitly defined when it is odr-used, needed for constant evaluation, or needed to determine exception specification(if necessary).