13 Templates [temp]

13.8 Name resolution [temp.res]

13.8.3 Dependent names [temp.dep]

13.8.3.3 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 current class ([expr.prim.this]) is dependent ([temp.dep.type]).
An id-expression is type-dependent if it is a template-id that is not a concept-id and is dependent; or if its terminal name is
  • associated by name lookup with one or more declarations declared with a dependent type,
  • associated by name lookup with a non-type template-parameter declared with a type that contains a placeholder type ([dcl.spec.auto]),
  • associated by name lookup with a variable declared with a type that contains a placeholder type ([dcl.spec.auto]) where the initializer is type-dependent,
  • associated by name lookup with one or more declarations of member functions of a class that is the current instantiation declared with a return type that contains a placeholder type,
  • associated by name lookup with a structured binding declaration ([dcl.struct.bind]) whose brace-or-equal-initializer is type-dependent,
  • associated by name lookup with a pack,
    [Example 1: struct C { }; void g(...); // #1 template <typename T> void f() { C arr[1]; auto [...e] = arr; g(e...); // calls #2 } void g(C); // #2 int main() { f<int>(); } — end example]
  • associated by name lookup with an entity captured by copy ([expr.prim.lambda.capture]) in a lambda-expression that has an explicit object parameter whose type is dependent ([dcl.fct]),
  • the identifier __func__ ([dcl.fct.def.general]), where any enclosing function is a template, a member of a class template, or a generic lambda,
  • a conversion-function-id that specifies a dependent type, or
  • dependent
or if it names a dependent member of the current instantiation that is a static data member of type “array of unknown bound of T” for some T ([temp.static]).
Expressions of the following forms are type-dependent only if the type specified by the type-id, simple-type-specifier, typename-specifier, or new-type-id is dependent, even if any subexpression is type-dependent:
Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
literal
sizeof unary-expression
sizeof ( type-id )
sizeof ... ( identifier )
alignof ( type-id )
typeid ( expression )
typeid ( type-id )
:: delete cast-expression
:: delete [ ] cast-expression
throw assignment-expression
noexcept ( expression )
requires-expression
[Note 1: 
For the standard library macro offsetof, see [support.types].
— end note]
A class member access expression is type-dependent if the terminal name of its id-expression, if any, is dependent or the expression refers to a member of the current instantiation and the type of the referenced member is dependent.
[Note 2: 
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.
— end note]
A braced-init-list is type-dependent if any element is type-dependent or is a pack expansion.
A fold-expression is type-dependent.
A pack-index-expression is type-dependent if its id-expression is type-dependent.