Is it C++ standard-compliant to define a variable using `A<int>::template B<int> x;`?

c++, c++11, compiler-construction, portability, templates

Solution

Even though it is a non-normative note, I think an answer can be given by n3797[temp.names]/6

As is the case with the `typename` prefix, the `template` prefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the `->` or `.` is not dependent on a template-parameter, or the use does not appear in the scope of a template.

In the OP's example, the prefix `template` is used outside the scope of a template, and the preceding nested-name-specifier is not dependent. Therefore, the prefix `template` is not required, but allowed here.

[expr.prim.general]/8

qualified-id: nested-name-specifier `template`opt unqualified-id

Plus [temp.names]/5

A name prefixed by the keyword `template` shall be a template-id or the name shall refer to a class template.

[temp.names]/1 says that `B<int>` is indeed a (simple-)template-id.

Problem

The following code is accepted by gcc, vc++, and clang. ``` template<class T> struct A { template<class U> struct B {}; }; int main() { A<int>::B<int> y; // OK as expected A<int>::template B<int> x; // Also OK! Is this standard-compliant? }; ``` Is it C++ standard-compliant to define a variable using `A<int>::template B<int> x;`?

Original source

Related problems