The error my compiler gives is:
main.cpp:11:5: error: call to function 'foo' that is neither visible in the template definition nor found by argument-dependent lookup
foo(T());
^
main.cpp:18:5: note: in instantiation of function template specialization 'quux<n::A>' requested here
quux<n::A>(); // Error (but works if you comment out the foo(int) declaration)
^
main.cpp:14:6: note: 'foo' should be declared prior to the call site or in namespace 'n'
void foo(n::A) {}
^
Which makes it clear what the problem is.
Commenting out void foo(int)
does not make it work however; that's just a bug/extension in your compiler.
You mention that you can't define void foo(n::A)
before quux()
, however when you say in the comments that you can't define it inside namespace n
, the reasons you give don't seem to apply. This should fix the problem without the other problems you mention.
template<typename T>
void quux()
{
foo(T());
}
namespace n {
void foo(n::A) {}
}
using n::foo; // in case there's any other code that depends on getting foo(n::A) from the global namespace
void foo(B) {} // this stays in the global namespace
If you can't move the definition of void foo(n::A)
to where it works with proper two-phase lookup (again, either before quux()
or inside namespace n
) there's a sort of hacky solution which may work for you: forward declare the proper overload of foo()
inside quux()
.
template<typename T>
void quux()
{
void foo(T);
foo(T());
}
The function eventually must be defined inside the same namespace as quux()
and it has to match the 'generic' forward declaration.
Or there's another alternative. It's only been fairly recent that most C++ compilers started offering correct two-phase name lookup, so there's a lot of code out there that isn't correct but which compilers want to support. If you can't change your code then it may be a good candidate for enabling a compatibility compiler option; my compiler takes the flag -fdelayed-template-parsing
to disable two-phase name lookup and instead always look names up in the instantiation context.