将“typedef”从基础传播到“模板”的派生类
我试图定义基类,其中只包含typedef。
template<typename T> class A { public: typedef std::vector<T> Vec_t; }; template<typename T> class B : public A<T> { private: Vec_t v; // fails - Vec_t is not recognized };
为什么在BI中收到一个错误,Vec_t无法识别,我需要明确写入?
typename A<T>::Vec_t v;
我相信这个问题是重复的,但我现在找不到。 C ++标准说,你应该完全符合14.6.2 / 3的名称:
在类模板或类模板成员的定义中,如果类模板的基类依赖于模板参数,则在类的定义点处不进行非限定名称查找模板或成员或在类模板或成员的实例化过程中。
UPD:最后我发现重复的: 在这里 。
在模板的情况下,有一些称为依赖和非依赖的名称。
如果名称取决于模板参数T的依赖名称,而其他依赖于参数T的名称则是独立名称。
这是规则:当查找非依赖名称(如Vec_t)时,编译器不查找依赖基类(如A)。 因此,编译器不知道他们甚至不存在types。
编译器不能认为Vec_t
是一个types,直到它知道T
为止,因为有一个潜在的A<T>
特殊化,其中A<T>:: Vec_t
是一个数据成员
所以解决scheme是使用typename
typename A<T>::Vec_t v; ← good
我build议你通过这个https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types 。
旧的(损坏的)链接: http : //www.parashift.com/c++-faq-lite/templates.html#faq-35.18
因为编译器不确定Vec_t
是什么types。 例如,对于T=int
, A<T>
可能是专门的, 不具有该特定的typedef
。
您需要明确限定使用Vec_t
因为编译器不知道Vec_t
来自哪里。
它不能假设A的结构,因为类模板A可能是专门的。 专业化可能包括一个不是typedef的Vec_t
,甚至可能根本不包含Vec_t
成员。
Vec_t不是一个依赖名称,编译器需要知道它是什么,而不需要实例化任何模板(在这种情况下是基类)。 这与以下事实并无二致:
template <class T> class X { std::string s; }
在这里,即使X没有实例化,编译器也需要知道std :: string,因为名称不依赖于模板参数T(就编译器而言)。
总而言之,模板基类中的typedef在派生类中似乎没有用处。 但是typedef对用户很有用。