This program does not compile (error: 'foo' is not a member of 'N'
):
namespace N {
// void foo();
}
template<class T>
void template_func(T t) {
N::foo(t);
}
But if we uncomment the declaration of void foo();
, it compiles. Demo.
Both versions have an error. foo
even if declared, takes no parameters. The following questions pose themselves.
- Why does one version compile, but not the other?
- Is there a rule in the C++ standard, that says something like this? "If the compiler is able to prove that no instantiations can be well-formed, it may (but is not required to) diagnose the error without instantiation."
My theory is the following (is it correct?). Inside template_func
N::foo
is a qualified name and a dependent name at the same time. Lookup of dependent names is postponed until the instantiation of the template. Looking up a name (if successful) results in tying the use of the name to a declaration of that name. But this process consists of two steps (let's now consider only qualified names, that look like a function call):
- Finding the name in the scope of the qualifier (in this example this means namespace
N
). This might find more than one name, since functions can be overloaded. - Checking whether the arguments can be passed to the found name(s). This includes finding a best match, if more than one
foo
is inN
. This way the use ofN::foo
is tied to anN::foo
declaration.
Actually the first step can be done without instantiation. The compiler seems to do it, and if no foo
is found, it diagnoses the error (which is optional to do). If at lease one foo
is found it does not bother with further analysis.