A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://timsong-cpp.github.io/cppwp/n4140/temp.dep below:

[temp.dep]

14.6.2 Dependent names [temp.dep]

Inside a template, some constructs have semantics which may differ from one instantiation to another. Such a construct depends on the template parameters. In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names. Expressions may be type-dependent (on the type of a template parameter) or value-dependent (on the value of a non-type template parameter). In an expression of the form:

postfix-expression ( expression-listopt )

where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if

If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation ([temp.point]) in both the context of the template definition and the context of the point of instantiation.

Example:

template<class T> struct X : B<T> {
  typename T::A* pa;
  void f(B<T>* pb) {
    static int i = B<T>::i;
    pb->j++;
  }
};

the base class name B<T>, the type name T::A, the names B<T>::i and pb->j explicitly depend on the template-parameter.  — end example ]

In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. [ Example:

typedef double A;
template<class T> class B {
  typedef int A;
};
template<class T> struct X : B<T> {
  A a;              };

The type name A in the definition of X<T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B<T>.  — end example ] [ Example:

struct A {
  struct B {  };
  int a;
  int Y;
};

int a;

template<class T> struct Y : T {
  struct B {  };
  B b;                            void f(int i) { a = i; }        Y* p;                         };

Y<A> ya;

The members A::B, A::a, and A::Y of the template argument A do not affect the binding of names in Y<A>.  — end example ]

14.6.2.1 Dependent types [temp.dep.type]

A name refers to the current instantiation if it is

The template argument list of a primary template is a template argument list in which the nth template argument has the value of the nth template parameter of the class template. If the nth template parameter is a template parameter pack ([temp.variadic]), the nth template argument is a pack expansion ([temp.variadic]) whose pattern is the name of the template parameter pack.

A template argument that is equivalent to a template parameter (i.e., has the same constant value or the same type as the template parameter) can be used in place of that template parameter in a reference to the current instantiation. In the case of a non-type template argument, the argument must have been given the value of the template parameter and not an expression in which the template parameter appears as a subexpression. [ Example:

template <class T> class A {
  A* p1;                          A<T>* p2;                       A<T*> p3;                       ::A<T>* p4;                     class B {
    B* p1;                          A<T>::B* p2;                    typename A<T*>::B* p3;                                        };
};

template <class T> class A<T*> {
  A<T*>* p1;                      A<T>* p2;                     };

template <class T1, class T2, int I> struct B {
  B<T1, T2, I>* b1;               B<T2, T1, I>* b2;               typedef T1 my_T1;
  static const int my_I = I;
  static const int my_I2 = I+0;
  static const int my_I3 = my_I;
  B<my_T1, T2, my_I>* b3;         B<my_T1, T2, my_I2>* b4;        B<my_T1, T2, my_I3>* b5;      };

 — end example ]

A name is a member of the current instantiation if it is

Example:

template <class T> class A {
  static const int i = 5;
  int n1[i];          int n2[A::i];       int n3[A<T>::i];    int f();
};

template <class T> int A<T>::f() {
  return i;         }

 — end example ]

A name is a dependent member of the current instantiation if it is a member of the current instantiation that, when looked up, refers to at least one member of a class that is the current instantiation.

A name is a member of an unknown specialization if it is

If a qualified-id in which the nested-name-specifier refers to the current instantiation is not a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the qualified-id is not instantiated; no diagnostic required. Similarly, if the id-expression in a class member access expression for which the type of the object expression is the current instantiation does not refer to a member of the current instantiation or a member of an unknown specialization, the program is ill-formed even if the template containing the member access expression is not instantiated; no diagnostic required. [ Example:

template<class T> class A {
  typedef int type;
  void f() {
    A<T>::type i;               typename A<T>::other j;                               }
};

 — end example ]

If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a qualified-id or class member access expression, the name in the qualified-id or class member access expression is looked up in the template instantiation context. If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous. [ Note: the result of name lookup differs only when the member of the current instantiation was found in a non-dependent base class of the current instantiation and a member with the same name is also introduced by the substitution for a dependent base class of the current instantiation.  — end note ]

A type is dependent if it is

Note: Because typedefs do not introduce new types, but instead simply refer to other types, a name that refers to a typedef that is a member of the current instantiation is dependent only if the type referred to is dependent.  — end note ]

14.6.2.2 Type-dependent expressions [temp.dep.expr]

Except as described below, an expression is type-dependent if any subexpression is type-dependent.

this is type-dependent if the class type of the enclosing member function is dependent ([temp.dep.type]).

A class member access expression ([expr.ref]) is type-dependent if the expression refers to a member of the current instantiation and the type of the referenced member is dependent, or the class member access expression refers to a member of an unknown specialization. [ Note: In an expression of the form x.y or xp->y the type of the expression is usually the type of the member y of the class of x (or the class pointed to by xp). However, if x or xp refers to a dependent type that is not the current instantiation, the type of y is always dependent. If x or xp refers to a non-dependent type or refers to the current instantiation, the type of y is the type of the class member access expression.  — end note ]

14.6.2.3 Value-dependent expressions [temp.dep.constexpr]

Except as described below, a constant expression is value-dependent if any subexpression is value-dependent.

An id-expression is value-dependent if:

Expressions of the following form are value-dependent if the unary-expression or expression is type-dependent or the type-id is dependent:

sizeof unary-expression
sizeof ( type-id )
typeid ( expression )
typeid ( type-id )
alignof ( type-id )
noexcept ( expression )

Note: For the standard library macro offsetof, see [support.types]. — end note ]

Expressions of the following form are value-dependent:

sizeof ... ( identifier )

An expression of the form &qualified-id where the qualified-id names a dependent member of the current instantiation is value-dependent.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4