c++name-lookupdependent-namequalified-name

Lookup of dependent qualified names


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):

  1. 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.
  2. Checking whether the arguments can be passed to the found name(s). This includes finding a best match, if more than one 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.


Solution

  • 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 ...