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.
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 usage 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):
N
). This might find more than one name, since functions can be overloaded.foo
is in N
. This way the usage of N::foo
is tied to an N::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.
Your analysis seems to be correct, and your code is ill-formed, no diagnostic required, regardless of whether void foo();
is commented out or not.
The part of the standard you're looking for is:
[temp.res.general]/6.1
The program is ill-formed, no diagnostic required, if:
— no valid specialization can be generated for a template ...