例子:
#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' 表示类型)