How does the placement of a concept definition change program behaviour

Viewed 70

I'm compiling this code with gcc 9.3 with -fconcepts.

The following compiles successfully

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

However, if I define the function f after I define the concept 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

then the program fails to compile with

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

This seems odd, since by the time g<int> needs to be instantiated, the definition of f should be visible. Could someone explain what's going on here?

Note that if I declare f before the concept definition, then even if I define f afterwards, the program compiles successfully.

1 Answers

ADL doesn't apply to int, so f(a) (with int a) is ill formed when not declared before.

You will have similar issue with:

void f(int){}

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

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