Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ADL does not work in constexpr functions (clang only)

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> ();
    ^
like image 628
Dr. Gut Avatar asked Aug 14 '19 21:08

Dr. Gut


1 Answers

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 :/

like image 50
Jarod42 Avatar answered Oct 21 '22 11:10

Jarod42