https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57433
Roman Perepelitsa <roman.perepelitsa at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |roman.perepelitsa at gmail dot com --- Comment #1 from Roman Perepelitsa <roman.perepelitsa at gmail dot com> --- Here's another example: template <class T> void Bar(T t) { Foo(t); } template <class T> void Foo(T) {} void Test() { Bar([]{}); } Clang rejects this code (expected behaviour), gcc accepts it (unexpected behaviour). Gcc erroneously finds Foo() by ADL. A more elaborate example: namespace n1 { template <class T> void Foo(T) {} auto F = []{}; auto G = []{ return []{}; }(); } // namespace n1 namespace n2 { void Test() { Foo(n1::F); // gcc and clang accept Foo(n1::G); // gcc accepts, clang rejects } } // namespace n2 F is a lambda defined in namespace scope of n1. When Test() calls Foo(n1::F), n1::Foo() is found via ADL. Nothing surprising here. Now, G is also a lambda from n1 but it's defined locally, in a function. When gcc resolves Foo(n1::G), it finds n1::Foo() by ADL, but clang doesn't. We can use structs instead of lambdas and the effect will be the same. We also can use regular non-template functions: namespace n1 { struct S {}; auto MakeQ = []{ struct Q {}; return Q(); }; using Q = decltype(MakeQ()); void Foo(S) {} void Foo(Q) {} } // namespace n1 namespace n2 { void Test() { Foo(n1::S()); // gcc and clang accept Foo(n1::Q()); // gcc accepts, clang rejects } } // namespace n2