The above error message indicates that the parsing reached the intended declarator-id,
but fp is seen as a name being referred to within an expression.

Alternative: require parentheses as part of a requires-clause

This alternative is self-explanatory. The parentheses act as a natural delimiter. This would normally cost one extra character because the opening parenthesis is likely to be placed immediately after the requires token:

template <typename T>
requires C1<T>
void f(T &&);

becomes

template <typename T>
requires(C1<T>)
void f(T &&);

Alternative: custom expression grammar for requires-clause

This alternative allows commonly written forms of constraint-expression to appear without parentheses. A sample grammar follows:

The author would like to thank Ville Voutilainen and Richard Smith for their input in discussions leading up to the production of this paper.
As usual, any mistakes are the responsibility of the author.