Defining a static data member of a templated class within a templated class

Viewed 251

I have a class template inside of another class template. The inner class has a static data member. I am struggling to provide a definition for it. The below example works in clang 3.8 but not in gcc-7.1

template <typename T>
struct Out {
  template <typename U>
  struct In {
    static int var;
  };
};

template <typename T>
template <typename U>
int Out<T>::template In<U>::var;

gcc gives the error:

error: template definition of non-template ‘int Out<T>::In<U>::var’
 int Out<T>::template In<U>::var;
                             ^~~

What do I gotta do to make gcc happy?


Edit: turns out getting rid of template make this work:

template <typename T>
template <typename U>
int Out<T>::In<U>::var;

Which still leaves the question, is template allowed here?

1 Answers

This type of definition would more commonly be seen without the template before In. The template keyword is not needed here because Out<T>::In is a "member of the current specialization".

For the rule specifying when the template keyword is required before a member name, see [temp.names]/4. For the definition of the technical term "member of the current specialization", see [temp.dep.type]/4.

But the keyword is in fact allowed there, since the grammar permits it between any :: and name, and the semantics require only that the name that follows is either used with template arguments or names a class template ([temp.names]/5), and there are no other rules in the Standard to forbid it. And as a note in [temp.names]/5 explains:

[ Note: 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. - end note]

Related