c++ - 将代码从非模板转换为模板时,类不是模板错误
问题描述
我从内联行中收到一个错误,它说“DListCursor 不是模板”(它在它自己的 .hpp 文件中),并且“模板参数列表必须与参数列表匹配”,我不明白它是如何不这样做的。
DListNode.hpp
template <typename ItemType>
class DListNode {
template <typename> friend class DListCursor;
public:
DListNode(ItemType item, std::shared_ptr<DListNode> prev = nullptr, std::shared_ptr<DListNode> next = nullptr);
#ifdef DEBUG
// ~DListNode() { std::cerr << "DListNode " << _item << std::endl; }
#endif
private:
ItemType _item;
std::shared_ptr<DListNode> _next;
std::weak_ptr<DListNode> _prev;
};
template <typename ItemType>
inline DListNode<DListCursor<ItemType>>::DListNode(ItemType item, std::shared_ptr<DListNode<ItemType>> prev, std::shared_ptr<DListNode<ItemType>> next) {
_item = item;
_prev = prev;
_next = next;
}
DListCursor.hpp - 我删除了 95% 的公共函数,因为我认为它们不相关。
template <typename ItemType>
class DListCursor {
public:
// constructor
DListCursor();
private:
void _copy(const DListCursor &source);
std::shared_ptr<DListNode> _find(size_t position) const;
std::shared_ptr<DListNode> _head, _cursor, _tail;
};
解决方案
前向声明类与前向声明模板类有点不同。
当您键入:
class ClassA;
甚至:
struct ClassB;
这告诉编译器一个类型存在并将被实现。
请注意,一旦您这样做,您就可以使用以下类型:
void stuff(ClassA& parameter_of_declared_class);
并且编译器期望一个看起来像这样的定义:
class ClassA { /* ... */ };
如果ClassA
实际上是模板,则函数声明语法将无效,因为它缺少模板参数。任何使用不完整类型的语法都将追溯无效。那真的很糟糕。
这就是为什么编译器必须提前知道您打算声明模板类型还是简单类型的原因。它们是不同类型的实体,应该以不同的方式声明。
一个模板类被转发声明如下:
template<typename> class ClassA;
请注意,它看起来很像您的朋友声明。
如果您有默认模板参数,它们也必须在声明中:
template<typename, typename = int> class ClassA;
推荐阅读
- javascript - 如何使用 Jest 模拟返回响应对象的方法
- python - 当 break 应该用于定义函数时,如何中断 while 循环?
- .net - 如何计算 AutoScaleMode.Font 中的比例因子?
- javascript - 获取编码字符作为响应
- ssl - 从 GKE pod 连接到 GCP redis 内存存储
- python - 从列表列表创建字典
- javascript - 如何解决此问题 TypeError:无法读取未定义的属性“位置”?
- excel - 如何证明/反驳 excel 和 google 表格中数据的可靠性
- merge - 如何使用 go-git 进行合并?
- java - Android 10 及更高版本上的即时应用内更新会在安装/重启后关闭应用