类模板的嵌套类可以“不完整”

时间:2015-01-03 23:55:17

标签: c++ templates nested-class

我不知道如何解释为什么在类模板inner中创建成员OuterTempl<T>是有效的,而在未模板化的类中这样做是违法的{ {1}}。

Outer

另见ideone

2 个答案:

答案 0 :(得分:4)

定义类时需要定义成员类型。但是,在实例化类模板之前,它不会被定义。任何类型的依赖类型都可以改变直到那时。只有在实例化类时才需要定义成员。

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

答案 1 :(得分:4)

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

  

类模板的成员类可以在类外定义   声明它的模板定义。
[注意: 会员   class必须在第一次使用之前定义,需要一个   实例化(14.7.1)。例如,

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
     

- 结束记录]

同样重要的是要提到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