我在看 Effective C++ 第四十二条,它指出C++ 在解析嵌套从属名称(nested dependent name)时并不会优先假定它是「类型」,于是得显式地在所有嵌套从属类型名称前统统加上typename
, 以声明它是嵌套从属类型名称(nested dependent type name)。但是这typename
不能用在成员初始化列表(member initialization list)里。问题来了:
假定varialble_
是Base
的数据成员,类型为int
. 那么
template class Derived: public Base { public: explicit Derived(int x) : Base::variable_(x) {} }
按照 C++ 的解析规则,Base
应该会被优先解析成非类型的名称,即Base
的一个数据成员,从而在Derived
构造函数里被初始化成x
.
但是这么一来,假定Base
是一种 class, 则
template class Derived: public Base { public: explicit Derived(int x) : Base::Nested(x) {} private: int second_variable_; }
怎么还能保证Base
会调用Base
构造函数来初始化其类对象,而不是把Base
当成一种Base
的数据成员呢?
我突然发现我把
Base::Nested(x)
和Base
的构造函数搞混了。Derived
作为派生类,只能在成员初始化列表内,调用基类Base
的构造函数,以及初始化它自己的数据成员。如果
Derived
继承Base::Nested
, 其实这就意味着Base::Nested
是一个类,编译器会知道成员初始化列表里Base::Nested(int x)
是一个构造函数的。其实 Effective C++ 第四十二条也指出了C++ 禁止在 base class lists 用typename
, 毕竟本来就画蛇添足。话说回来,在成员初始化列表内,要把
Base::variable_
解析成一个类型,也没有意义。