why the keyword template can appear in a qualified-id formed by a class-head-name

Viewed 191

Consider the following two examples:

template<class>
struct A{
  template<class...>
  struct B{};
};
template<class T>
template<class U>
struct A<T>::template B<U>{  // Notice this declaration
}; 
int main(){
}

This code is accepted by all compilers except GCC 7.x. However, IIUC, I have to say that the declaration for B<U> shouldn't be supported by the grammar, My reason is: class#nt:class-head-name

nested-name-specifier opt class-name

There is no optional keyword template before class-name, so it should be an invalid declaration, as far as now, I think GCC 7.x is right.

Another example is:

#include <iostream>
template<class>
struct A{
    template<class>
    struct B{
       template<class...>
       struct C;
    };
};
template<class T>
template<class U>
template<class Y>
struct A<T>::template B<U>::C<Y>{  // #2

};
int main(){

}

According to this rule:
temp.names#4

The keyword template is said to appear at the top level in a qualified-id if it appears outside of a template-argument-list or decltype-specifier. In a qualified-id of a declarator-id or in a qualified-id formed by a class-head-name or enum-head-name, the keyword template shall not appear at the top level.

As aforementioned, the first case may be prohibited by the relevant grammar. Instead, according to [temp.names#4], the second case should still be an invalid declaration. The rule explicit says that the keyword template shall not appear at the top level in qualified-id formed by a class-head-name. So, I wonder why the second case can be accepted by all compilers?

How to interpret these two examples, the grammar for class-head-name and the rule [temp.names#4]?

0 Answers
Related