Go back when typename is required. Β§14.6 [temp.res] / p3, all citations from N4140:
When a qualified identifier is intended to indicate a type that is not a member of the current instance (14.6.2.1) and its inested-name-specifier refers to a dependent type, it must be a prefix with the typename keyword, forming a type-name-specifier.
The qualified identifier in this case is B<decltype(throw (int*)n)>::Type (and the delete version, for which the analysis is exactly the same). Therefore, typename is required if the sub-name specifier or B<decltype(throw (int*)n)>:: is of the dependent type.
Β§14.6.2.1 [temp.dep.type] / p8 says that with six unrelated bullets itβs omitted that
Type depends if it
[...]
(8.7) is the identifier of a simple template in which either the template name is a template parameter or any of the template arguments is a type or expression dependent on the type or depending on the cost, or
(8.8) - denoted by the expression decltype( ) , where the expression depends on the type (14.6.2.2).
B<decltype(throw (int*)n)> is a simple identifier template. Template name B not a template parameter. The only argument to decltype(throw (int*)n) not an expression, so B<decltype(throw (int*)n)> depends only if decltype(throw (int*)n) is a dependent type. decltype(throw (int*)n) , in turn, on the 8.8 bullet, depends only if throw (int*)n depends on the type. But we know that according to Β§14.6.2.2 [temp.dep.expr] / p4:
The expressions of the following forms never depend on the type (because the type of the expression cannot be dependent):
[...]
:: opt delete cast-expression
[...]
throw assignment expression opt
[...]
Therefore, throw (int*)n is type independent, so decltype(throw (int*)n) not a dependent type, so B<decltype(throw (int*)n)> not a dependent type, so typename not required for B<decltype(throw (int*)n)>::Type and so yes, this is a compiler error.