我在看 Effective C++ 第四十二条,它指出 C++ 在解析嵌套从属名称(nested dependent name)时并不会优先假定它是「类型」,于是得显式地在所有嵌套从属类型名称前统统加上 typename
, 以声明它是嵌套从属类型名称(nested dependent type name)。但是这 typename
不能用在成员初始化列表(member initialization list)里。问题来了:
假定 varialble_
是 Base<T>
的数据成员,类型为 int
. 那么
template<typename T>
class Derived: public Base<T> {
public:
explicit Derived(int x) : Base<T>::variable_(x) {}
}
按照 C++ 的解析规则,Base<T>::variable_
应该会被优先解析成非类型的名称,即 Base<T>
的一个数据成员,从而在 Derived
构造函数里被初始化成 x
.
但是这么一来,假定 Base<T>::Nested
是一种 class, 则
template<typename T>
class Derived: public Base<T> {
public:
explicit Derived(int x) : Base<T>::Nested(x) {}
private:
int second_variable_;
}
怎么还能保证 Base<T>::Nested(x)
会调用 Base<T>::Nested(int x)
构造函数来初始化其类对象,而不是把 Base<T>::Nested
当成一种 Base<T>
的数据成员呢?
I suddenly realized that I had confused the constructors of
Base<T>::Nested(x)
andBase<T>
.Derived
As a derived class, it can only call the constructor of the base classBase<T>
and initialize its own data members within the member initialization list.If
Derived
inheritsBase<T>::Nested
, this actually means thatBase<T>::Nested
is a class , and the compiler will know thatBase<T>::Nested(int x)
in the member initialization list is a constructor. In fact, Effective C++ Article 42 also points out that C++ prohibits the use oftypename
in base class lists. After all, it is superfluous.Having said that, in the member initialization list,
Base<T>::variable_
needs to be parsed into a type, does not make sense.