All standard references below refer, unless noted otherwise, to N4861 (March 2020 post-Prague working draft/C++20 DIS).
This is a Clang bug, and GCC is correct to reject the program, as per [dcl.decl]/4 (as well as [temp.constr.decl]/1) [emphasis mine]:
The optional requires-clause in an init-declarator or
member-declarator shall be present only if the declarator declares a templated function ([dcl.fct]). When present after a declarator,
the requires-clause is called the trailing requires-clause. [...]
The same paragraph also contains a (non-normative) example explicitly pointing out the OP's example as ill-formed:
[ Example:
void f1(int a) requires true; // error: non-templated function
template<typename T>
auto f2(T a) -> bool requires true; // OK
// ...
— end example ]
We may note that in an earlier version of the (to become C++20) working draft, N4810, [dcl.decl]/4 had a weaker requirement for where requires-clauses were allowed to appear:
The optional requires-clause (Clause 13) in an init-declarator or member-declarator shall not be present when the declarator does not declare a function (9.2.3.5). [...]
[ Example:
void f1(int a) requires true; // OK
// ...
— end example ]
where the non-normative example of the use case of the OP was explicitly shown as well-formed. The original intent there was arguably to allow constraining of non-template member functions of class templates based on the template parameters of the class template:
#include <iostream>
template<bool B>
struct S {
void f() requires B { std::cout << "true
"; }
void f() requires (!B) { std::cout << "false
"; }
};
int main() {
S<true>{}.f(); // true
S<false>{}.f(); // false
}
this is still allowed in the final state (intended for C++20) of [dcl.decl]/4 in N4861, where the restriction is to that of a templated function (see templated entity in [temp.pre]/8, particularly [temp.pre]/8.3), which does not only cover function templates (and function template members of non-templates and template class templates), but also non-template member functions of class templates.
Clang bug report:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…