This minimal program
template <typename X>
void foo (X x)
{
bar (x);
}
template <typename X>
void bar (X x)
{
}
int main ()
{
foo ([]{});
}
compiles with gcc (4.8.5 and 5.3) and fails to compile with clang (3.7)
My analysis is as follows.
bar
is used in foo
and declared after foo
, so it is not visible at foo
definition point. The only way bar
can be found at foo
instantiation point is via argument-dependent lookup.
The only argument to both foo
and bar
is a lambda defined in main
.
Apparently gcc regards its type as declared in the global namespace, while clang does not. Thus, gcc can find bar
via ADL and clang cannot.
Same thing happens when we use a type defined locally in main
:
int main ()
{
struct K{};
foo (K()); // gcc compiles, clang complains
}
It looks like gcc is in the wrong here. The type of the lambda according to the standard is unnamed (expr.prim.lambda/3), so it should not belong to any namespace. The local type supposedly shouldn't belong to the global namespace either.
Is the analysis correct? Is this a known gcc bug?
This question is inspired by this question.