例子:
#include <utility> // std::pair
#include "vertex.hpp" // IVertex class
template <typename Key>
class IEdge {
public:
using VertexPtr = IVertex<Key>*;
using Endvertices = std::pair<VertexPtr, VertexPtr>;
// ...
public:
Endvertices& endvertices() noexcept = 0;
};
template <typename Key = int>
class Edge : public IEdge<Key> {
public:
// interface: IEdge
Endvertices& endvertices() noexcept override;
};
编译器会生成大量与缺少关键字相关的错误typename
,添加后者也无济于事。
问:怎么处理?我是否应该在每个别名前面加上带有当前模板参数的基类,例如:
typename IEdge<Key>::Envertices
如果是这样,请解释为什么在使用模板的情况下这是必要的。
是的,在子类中,当引用基类的类型时,必须以类名和 为前缀
typename
。关键是在实例化模板之前,IEdge
基模板类中某些组件的存在是未知的(因为它们可能会因参数而异Key
)并且编译器无法确定标识符的来源Endvertices
。您在这里混合了两个独立的问题。
首先,
typename
它们与此代码中没有错误无关。此代码中的错误是由于在基类是依赖类型的情况下,正常的非限定名称搜索不会查找该基类。Endvertices
因此,似乎找不到派生类中使用的非限定名称。(例如,参见Class Hierarchy 2 中的错误)typename
这里没有什么。难怪添加typename
没有帮助。其次,如果我们谈论的是基类的字段或方法,问题可以通过通过访问
this->...
或通过限定名称访问来解决IEdge<Key>::...
。对于类型名称,只有第二个选项适用。由于类型IEdge<Key>
是依赖的,这就是规则生效的地方,需要typename
引用嵌套类型。(例如,参见C++ 错误相关名称不是类型,前缀为 'typename' 表示类型)