- We're introducing a new definition: "instantiation-dependent". When encoding a signature that contains a non-dependent expression like "sizeof(int)", existing practice it to just replace that by the resulting value, or in some cases, by the encoding for a literal representing that value. For example:
template<class T, int N> struct S {};
template<class T> void f(S<T, sizeof(int)>);
// "sizeof(int)" is encoded as "Li4E" on typical platforms;
// i.e., as if we'd written "4" instead.
Similarly, something like "decltype(int)" is just encoded as the known underlying type.
However, there are non-dependent expressions and types that can still fail instantiation. With the new SFINAE rules, several template declarations differing only in such expressions can be written such that their encodings don't collide. So reducing a sizeof/decltype that is applied to such an expression to a literal isn't workable. Here is an example of the idea:
template<class T> auto f(T *p)->decltype(sizeof(sizeof(T)));
"sizeof(sizeof(T))" is neither type-dependent nor value-dependent, but if T is e.g. a function type, that declaration will be "SFINAEed out".
So an "instantiation-dependent" expression or type is one that is either type-dependent or value-dependent, or one that contains a type-dependent or value-dependent sub-expression. decltype, sizeof, and alignof must be fully encoded if (and only if) their operand is "instantiation-dependent"; otherwise, the resulting type/value is encoded instead.