Can't understand name lookup differences between an int and a user defined type - perhaps ADL related

Viewed 159

Why does the following code compile:

template<typename T>
void foo(T in) { bar(in); }

struct type{};
void bar(type) {}
int main() { foo(type()); }

When the following does not:

template<typename T>
void foo(T in) { bar(in); }

void bar(int) {}
int main() { foo(42); }

Compiling with GnuC++ 7:

a.cpp: In instantiation of 'void foo(T) [with T = int]':
a.cpp:9:20:   required from here
a.cpp:2:21: error: 'bar' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
 void foo(T in) { bar(in); }
                  ~~~^~~~
a.cpp:8:6: note: 'void bar(int)' declared here, later in the translation unit void bar(int) {}

I would assume that MSVC would compile both (as it does) but that GCC would reject both since GCC/Clang have proper two phase name lookup...

2 Answers
Related