概念定义的放置如何改变程序行为

How does the placement of a concept definition change program behaviour

我正在用 gcc 9.3-fconcepts 编译这段代码。

下面编译成功

void f(int) {}             // 1

template<typename T>       // 2 
concept C = requires (T a) 
{ { f(a) }; };

template<C T>              // 3
void g() { f(42); }

int main() { g<int>(); }   // 4

但是,如果我定义函数 f after 我定义概念 C,

template<typename T>       // 2 
concept C = requires (T a) 
{ { f(a) }; };

void f(int) {}             // 1

template<C T>              // 3
void g() { f(42); }

int main() { g<int>(); }   // 4

然后程序无法编译

error:
line 4: cannot call function g
because
line 3: constraint not satisfied
because
line 2: required expression f(a) would be ill-formed

这看起来很奇怪,因为在需要实例化 g<int> 时,f 的定义应该是可见的。有人可以解释一下这是怎么回事吗?

注意,如果我在概念定义之前声明了f,那么即使我之后定义了f,程序也能编译成功。

ADL 不适用于 int,因此 f(a)(带有 int a)在之前未声明时格式错误。

您将遇到类似的问题:

void f(int){}

template<typename T>
void g(T t)
{
    f(t);
}
void f(char){}

void h() { g('*'); } // Call f(int)