Since there are questions about how unqualified names may depend or how an unqualified name search can be applied to dependent names:
Route analysis: determining how we analyze the operator
If a dependent name is found in a template, it is always assumed that it should not indicate a type, unless a search by name that is applicable detects that it is a type, or we add the name using typename :
template<typename T> void f() { T f0;
This search for a name to determine whether it is a type is always performed at the template definition point for all dependent names: it directs the next analysis in a specific direction. In the second expression, we will analyze T *f1 as a pointer declaration, but not as a multiplication. In the last statement, we assumed that in the case of a preparametric value, that T::name not a type and is trying to parse it as an expression. This will fail because we expect a semicolon or some operator after T::name . This search, regardless of whether it is a type, does not affect the meaning of the name in subsequent steps: it will not yet associate the name with any declaration.
Actual analysis
After we determine which names are types and what are not, we will actually analyze the pattern. Names that are not dependent, that is, those that are not visible in an area that depends or are not explicitly dependent on other rules, are looked at where they are used in the template, and their meaning is not influenced by any declaration visible when creating an instance.
Names that depend are looked up when creating an instance, both in the definition of the template, where they are used, and when creating their template. This is also true for unqualified names that depend on:
template<typename T> struct Bar { void bar() { foo(T()); } }; namespace A { struct Baz { }; void foo(Baz);
Unqualified foo dependent on the standard because the argument of T() is type dependent. When creating an instance, we will look for functions called foo , using the search for an unqualified name around the template definition and using a search argument dependent (which roughly means in the T namespace) around the template definition and the point at which we instantiate it (after main ). Then an argument-dependent search will find foo .
If Bar now has a dependent base class, an unskilled search should ignore this dependent base class:
template<typename T> struct HasFoo { }; template<typename T> struct Bar : HasFoo<T> { void bar() { foo(T()); } }; namespace A { struct Baz { }; void foo(Baz);
This should find A::foo , although an unqualified name lookup will find a member function of the class if it was done (ADL will not find additional functions if a member function of the class was found). But an unqualified namelookup will not find this function, because it is a member of a dependent base class, and those are ignored during an unqualified name lookup. Another interesting case:
template<typename> struct A { typedef int foo; operator int() { return 0; } };
The standard states that when searching for foo in the name operator foo we will search independently both in the region p-> (which is in the region of class A<T> ) and in the region in which the full expression appears (which is the region of C<T>::c as an unqualified name) and compares two names, if found, whether they denote the same type. If we do not ignore the dependent base class A<T> during the search in the scope of the full expression, we will find foo in the two base classes, which will be ambiguous. Ignoring A<T> will mean that we will find the name once when we search in p-> , and at another time when we search in TypeNameSugar .