gcc is right. It is because Baz
is a namespace and namespaces are parsed top to bottom, so the declaration of Baz::Print
is not visible from inside Foo
(since it is beneath it).
When the template is instantiated, only names visible from the template definition are considered, not counting Koenig lookup (which wouldn't change anything in your case).
If Baz
were a struct or class, your code would work, since these are parsed in two phases (first declarations, then bodies), so anything declared in a struct or class is visible inside eg. member functions, regardles of their order in the source file.
You can make it work by declaring Baz::Print
before Foo
.
Quoting the standard:
14.6.3 Non-dependent names
Non-dependent names used in a template definition are found using the usual name lookup and bound at the
point they are used.
14.6.4 Dependent name resolution
In resolving dependent names, names from the following sources are considered:
- Declarations that are visible at the point of definition of the template.
- Declarations from namespaces associated with the types of the function arguments both
from the instantiation context (14.6.4.1) and from the definition context.
(end quotation)
When Print
is nondependent (as it is now), it wouldn't be found since it is looked up before its declaration (in the template definition context). If it were dependent, it wouldn't be the first case (same as when nondependent), and Baz
is not associated with int (the template parameter) in any way, so it wouldn't be searched according to the second case either.