Name binding and dependent names (C++ only)

Name binding is the process of finding the declaration for each name that is explicitly or implicitly used in a template. The compiler might bind a name in the definition of a template, or it might bind a name at the instantiation of a template.

A dependent name is a name that depends on the type or the value of a template parameter. For example:
template<class T> class U : A<T>
{
  typename T::B x;
  void f(A<T>& y)
  {
    *y++;
  }
};      
The dependent names in this example are the base class A<T>, the type name T::B, and the variable y.
The compiler binds dependent names when a template is instantiated. The compiler binds non-dependent names when a template is defined. Consider the following example:
#include <iostream>
using namespace std;

void f(double) { cout << "Function f(double)" << endl; }

template <class A> struct container{ // point of definition of container
   void member1(){
      // This call is not template dependent, 
      // because it does not make any use of a template parameter.
      // The name is resolved at the point of definition, so f(int) is not visible.
      f(1); 
   }
   void member2(A arg);
};

void f(int) { cout << "Function f(int)" << endl; }

void h(double) { cout << "Function h(double)" << endl; }

template <class A> void container<A>::member2(A arg){ 
   // This call is template dependent, so qualified name lookup only finds
   // names visible at the point of instantiation.
   ::h(arg);  
}

template struct container<int>; // point of instantiation of container<int>

void h(int) { cout << "Function h(int)" << endl; }

int main(void){   
   container<int> test;   
   test.member1();
   test.member2(10);
   return 0;
}
The output of this example:
Function f(double)
Function h(double)

The point of definition of a template is located immediately before its definition. In this example, the point of definition of the template container is located immediately before the keyword template. Because the function call f(1) does not depend on a template parameter, the compiler considers names declared before the definition of the template container. Therefore, the function call f(1) calls f(double). Although f(int) is a better match, it is not in scope at the point of definition of container.

The point of instantiation of a template is located immediately before the declaration that encloses its use. In this example, the point of instantiation of container<int> is the location of the explicit instantiation. Because the qualified function call ::h(arg) depends on the template argument arg, the compiler considers names declared before the instantiation of container<int>. Therefore, the function call h(arg) calls h(double). It does not consider h(int), because this function is not in scope at the point of instantiation of container<int>.

Point of instantiation binding implies the following:
  • A template parameter cannot depend on any local name or class member.
  • An unqualified name in a template cannot depend on a local name or class member.
C++11
The decltype feature can interact with template dependent names. If the operand expression in the decltype(expression) type specifier is dependent on template parameters, the compiler cannot determine the validity of expression before the template instantiation, as shown in the following example:
template <class T, class U> int h(T t, U u, decltype(t+u) v);
In this example, the compiler issues an error message if the operand t+u is invalid after the instantiation of the function template h.

For more information, see The decltype(expression) type specifier (C++11)

C++11