wg21.cmeerw.net

Template Parameter Scope [basic.scope.temp]

The declarative region of the name of a template parameter of a template template-parameter is the smallest template-parameter-list in which the name was introduced.

The declarative region of the name of a template parameter of a template is the smallest template-declaration in which the name was introduced. Only template parameter names belong to this declarative region; any other kind of name introduced by the declaration of a template-declaration is instead introduced into the same declarative region where it would be introduced as a result of a non-template declaration of the same name. [Example:

  namespace N {
    template<class T> struct A{};               // line 2
    template<class U> void f(U){}               // line 3
    struct B {
      template<class V>friend int g(struct C*); // line 5
    };
  }

The declarative regions of T , U and V are the template-declarations on lines 2, 3 and 5, respectively. But the names A , f , g and C all belong to the same declarative region—namely, the namespace-body of N . ( g is still considered to belong to this declarative region in spite of its being hidden during qualified and unqualified name lookup.) —end example]

The potential scope of a template parameter name begins at its point of declaration (6.4.2 [basic.scope.pdecl]) and ends at the end of its declarative region. [Note: this implies that a template-parameter can be used in the declaration of subsequent template-parameters and their default arguments but cannot be used in preceding template-parameters or their default arguments. For example,

  template<class T, T* p, class U = T> class X { /* ... */ };
  template<class T> void f(T* p = new T);

This also implies that a template-parameter can be used in the specification of base classes. For example,

  template<class T> class X : public Array<T> { /* ... */ };
  template<class T> class Y : public T { /* ... */ };

The use of a template parameter as a base class implies that a class used as a template argument must be defined and not just declared when the class template is instantiated. —end note]

The declarative region of the name of a template parameter is nested within the immediately-enclosing declarative region. [Note: as a result, a template-parameter hides any entity with the same name in an enclosing scope (_N4868_.6.4.10 [basic.scope.hiding]). [Example:

  typedef int N;
  template<N X, typename N, template<N Y> class T>
    struct A;

Here, X is a non-type template parameter of type int and Y is a non-type template parameter of the same type as the second template parameter of A . —end example] —end note]

[Note: because the name of a template parameter cannot be redeclared within its potential scope (13.8.2 [temp.local]), a template parameter's scope is often its potential scope. However, it is still possible for a template parameter name to be hidden; see 13.8.2 [temp.local]. —end note]

Read the original on wg21.cmeerw.net ↗