在模板类中定义模板类的静态数据成员
我在另一个类模板中有一个类模板。内部类有一个静态数据成员。我正在努力为它提供一个定义。下面的例子作品在铛3.8,但不是在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给出了错误:
error: template definition of non-template ‘int Out<T>::In<U>::var’
int Out<T>::template In<U>::var;
^~~
什么是我必须做的,使GCC幸福吗?
编辑:原来摆脱template
,使这项工作:
template <typename T>
template <typename U>
int Out<T>::In<U>::var;
仍然留下一个问题,是template
允许在这里?
在In
之前没有template
这种类型的定义将更常见。此处不需要template
关键字,因为Out<T>::In
是“当前专业化的成员”。
有关规定成员名称前需要使用template
关键字的规则,请参见[temp.names]/4。关于技术术语“当前专业化成员”的定义,请参见[temp.dep.type]/4。
但是关键字实际上是允许的,因为语法允许它在任何::
和名称之间,并且语义只要求下面的名称要么与模板参数一起使用,要么命名类模板([temp.names ]/5),并且标准中没有其他规则禁止它。并且[temp.names]/5中的说明解释:
[ Note: As is the case with the
typename
prefix, thetemplate
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]
当我省略'template'作为'Out'的静态数据成员时,我仍然感到困惑 –
允许多余'template'消歧器被允许改变的规则C++ 11。具体而言,“使用的部分不出现在模板范围内”。 – Oktalist
不仅允许,而且还需要。此时,编译器不知道是否Out :: In是一个typename /成员/模板。它会猜测成员,并猜测你想要在 ::,这是一个错误。较新的gccs,如上所述,在这里提供有用的诊断;之前,情况更糟。 –
lorro
@lorro我认为这是必要的,你给的理由。我的困惑得到了证实 –