Законные проявления <=> в коде pre-С++ 20

Разбежавшись в wandbox, я обнаружил, что clang действительно выдаст предупреждение, если он увидит <=> на С++ 17 или ранее.

warning: '<=>' is a single token in C++2a; add a space to avoid a change in behavior [-Wc++2a-compat]

Я попытался выяснить, как написать законный пример использования последовательности символов <=> в С++ 17, но то, что я придумал, все очень надуманно. Наиболее вероятный пример (imo) предполагает использование шаблона:

struct A {
  bool operator<=(A) const { return true; }
};

template <auto Cmp>
void f() { }

int main() {
  f<&A::operator<=>();
}

живой пример

Все остальное по-прежнему включает прямое упоминание функции сравнения по имени operator<=. Есть ли более общий вид <=> который я не могу себе представить, что побудило бы разработчиков кланов добавить это предупреждение?

Ответ 1

Существуют и другие возможные синтаксисы, которые не обязательно включают аргумент шаблона. Например,

class A {};
bool operator<=(A,A) { return true; }

class B {};
bool operator>(bool(*)(A,A), B) { return false; }

int main()
{
    B b;
    return operator <=> b;
}

Но верно, что все такие примеры имеют operator ключевого слова непосредственно перед появлением <=>.

Единственный способ доказать такое утверждение - сделать исчерпывающий поиск по всей грамматике C++, удобно показанной в одном месте в Приложении A стандарта C++ 17 и некоторых других стандартных версиях.

Во-первых, обратите внимание, что из-за правила Maximal Munch, если следующие исходные символы после предыдущих токенов препроцессора были проанализированы, <=>, тогда C++ 17 и ранее всегда будут обрабатывать первый токен как <=. Следующий токен действительно может быть > или >> или >= или >>=.

Единственными правилами грамматики, связанными с токеном <= являются:

складчато-оператор:

<=

реляционная выражение:

реляционное выражение <= сдвиг-выражение

оператор:

<=

Символьный оператор символа грамматики используется только в:

складчато-выражение:

( сбрасывание-выражение ... )

(... fold-operator cast-expression )

( литье-выражение сбрасывает-операторы ... fold-operator cast-expression )

Так как кратный-оператор, <= должен следовать либо ... лексема (что, конечно, не > или >> или >= или >>=), или монолитно-выражение. Либо, как оператор сгиба или в реляционном выражении, <= токен может сопровождаться выражением-выражением или сдвигом-выражением, которое является как ограниченным видом выражения. Но нет правила грамматики, позволяющего начинать любое выражение с > или >> или >= или >>=.

Это оставляет только символ символа символа, найденный только в:

оператор-функция-ID:

operator оператора

который показывает, что operator ключевого слова должен быть непосредственно перед <= который может вместо этого оказаться частью <=> в C++ 20.