是否在声明内的参数替换后评估 require-clauses?

Are require-clauses evaluated after parameter substitution inside declarations?

在 C++ 标准 N4618/[temp.deduct] (§14.8.2) 中,以下示例 (§14.8.2/7) 演示了如何按词法顺序执行模板参数替换:

 template <class T> struct A { using X = typename T::X; };
 template <class T> typename T::X f(typename A<T>::X);
 template <class T> void f(...) { }
 template <class T> auto g(typename A<T>::X) -> typename T::X;
 template <class T> void g(...) { }
 void h() {
    f<int>(0);// OK, substituting return type causes deduction to fail
    g<int>(0);// error, substituting parameter type instantiates A<int>
}

我原以为 requires-clauses 内容也会在声明内容之前被评估。我预计以下修改不会产生任何编译错误:

 template <class T> struct A { using X = typename T::X; };
 template <class T> typename T::X f(typename A<T>::X);
 template <class T> void f(...) { }
 template <class T>
 requires false
 auto g(typename A<T>::X) -> typename T::X;
 template <class T> 
 requires true
 void g(...) { }
 void h() {
    f<int>(0);// OK, substituting return type causes deduction to fail
    g<int>(0);// error, substituting parameter type instantiates A<int>
}

其实GCC告诉我还是有错误。是否是概念TS中所述的行为?

是的。请参阅 N4630 [temp.deduct]/5 中的注释:

The satisfaction of constraints (14.10) associated with the function template specialization is determined during overload resolution (13.3), and not at the point of substitution.