The following code compiles with MSVC and gcc, but not with clang. Why is that so?
It seems like if ADL would not work if CallFoo () is constexpr. See the comment.
template <class T>
constexpr void CallFoo  ()          // Remove constexpr to fix clang compilation error.
{
    Foo (T ());
}
class Apple {};
int main ()
{
    CallFoo<Apple> ();
}
constexpr void Foo (Apple)
{
}
Clang error message (see on godbolt.org):
<source>:4:5: error: use of undeclared identifier 'Foo'
    Foo (T ());
    ^
<source>:13:5: note: in instantiation of function template specialization 'CallFoo<Apple>' requested here
    CallFoo<Apple> ();
    ^
                Declaration should be visible at the point of instantiation, so clang has right to reject your code. Reordering functions fixes compilation:
constexpr void Foo (Apple)
{
}
int main ()
{
    CallFoo<Apple> ();
}
Demo
Fact is that end of file is a point of instantiation too, and gcc/MSVC should only consider this one :/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With