类模板的嵌套类可以是"不完全的"。

4

我不知道该如何解释为什么在类模板OuterTempl<T>中创建成员变量inner是合法的,而在非模板类Outer中却是非法的。

// Non-template version
struct Outer
{
    struct Inner;
    Inner inner;   // incomplete type (I get this)
};

struct Outer::Inner
{
};

// Template version
template<typename T>
struct OuterTempl
{
    struct InnerTempl;
    InnerTempl inner; // OK ... Huh!?
};

template<typename T>
struct OuterTempl<T>::InnerTempl
{
};

int main()
{
}

另请参阅ideone

2个回答

4

是的 - 参考[temp.mem.class]/1:

A member class of a class template may be defined outside the class template definition in which it is declared.
[ Note: The member class must be defined before its first use that requires an instantiation (14.7.1). For example,

template<class T> struct A {
    class B;
};

A<int>::B* b1;  // OK: requires A to be defined but not A::B

template<class T> class A<T>::B { };

A<int>::B b2;   // OK: requires A::B to be defined

— end note ]

重要的是要提到,上述说明使用的 Inner 所构成的 inner 的定义仅在需要时才被实例化:

除非一个成员已经被显式地实例化或专门化,否则当特化在需要成员定义存在的上下文中被引用时,该成员的专门化将隐式实例化。

由于您的代码中没有出现 OuterTempl 的实例化,因此定义 inner 从未实例化,也不需要实例化 Inner。这种声明的嵌套类类型的完整性仅在实例化点上是必需的。虽然您没有在此处实例化 OuterTempl,但如果您在 Inner 的定义之前进行实例化,则代码将无法运行。
换句话说,
template<typename T>
struct OuterTempl
{
    struct InnerTempl;
    InnerTempl inner;
};

template struct OuterTempl<int>; // Bad - Ill-formed (NDR?)

template<typename T>
struct OuterTempl<T>::InnerTempl {};

template struct OuterTempl<int>; // Fine

Demo.


4

在定义类时需要定义成员类型。然而,类模板只有在实例化时才会被定义。在那之前,任何依赖类型都可能发生变化。成员的定义只有在类被实例化时才是必需的。

另一方面,非模板类的定义是需要知道其成员大小的定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接