This is a question of why not brick. That is, a question that asks why something false is true. This is not the case when in C ++ your code is legal.
A living example , as you can see in gcc 4.8, this does not actually compile.
I assume the question is "why gcc 4.6 allows you to compile this code." One of the things that compilers did at an early stage when writing template
extenders was to treat them as something like macros. Very little would be done when they announced, and everything would look when they instantiated.
Compilers now tend to do more things when a template
declared, and less when it is created. This is what the C ++ standard requires, or at least closer.
As it happens, ADL can get around this: bar
requests that find bar
through ADL should not be visible at the point where foo
is written, but rather at the instantiation point.
The gcc 4.8 error message is pretty clear:
prog.cpp: In instantiation of 'void foo(T) [with T = int]': prog.cpp:16:7: required from here prog.cpp:6:10: error: 'bar' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive] bar(x); // OKAY ^ prog.cpp:10:6: note: 'template<class T> void bar(T)' declared here, later in the translation unit void bar(T x) ^
these requirements can be changed or clarified in C ++ 11, so it is entirely possible that the behavior of gcc 4.6 was legal in accordance with the C ++ 03 standard.
source share