问题遇到的现象和发生背景
在用VS2019编写一个双向链表模板类SLL时,我打算用头文件和源文件分离的写法。
//h文件
#pragma once
#include"pch.h"
#include"SLL_.cpp"
#ifndef SLL_
#define SLL_
//定义第二元素类element2,只能被SLL等类创建和销毁,重载了后置自增和自减运算符
template <typename D>class element2
{
D* data;
element2<D>* last;
element2<D>* next;
element2(D* any) :data(any), last(nullptr), next(nullptr) {}
~element2() {}
public:
D* getdata();
element2& operator--(int);
element2& operator++(int);
template <typename D>friend class SLL<D>;
}
template <typename D>class SLL
{ element2<D>* frist_element;
element2<D>* final_element;
unsigned int size;
protected:
//负责将前一个数据生成新元素插入到后一个元素之后,nullptr则表示插入到第一个元素前
template <typename F>
bool add_element2(const D* any,const element2<D>* laster);
//负责将传入指针所指的元素从表中删除
template <typename F>bool cut_element2(element2<D>* cutder);
}
//cpp文件
#pragma once
#include"SLL_.h"
#include"pch.h"
template <class D> D* element2<D>:: getdata() {
return data;
}
template<typename D>
element2<D>& element2<D>::operator++(int a) {
for (; a > 0; a--) {
this = this.next;
}
return this;
}
template<typename D>element2<D>& element2<D>::operator--(int a) {
for (; a > 0; a--) {
this = this.last;
}
return this;
};
template <typename D>
bool SLL<D>:: add_element2(const D* any, const element2<D>* laster)
{
element2<D>* adder = new element2(any);
……
}
但是,在编写完源文件和头文件之后,点击生成时却发现源文件区域集体报错。
错误 C2988 不可识别的模板声明/定义 SLL D:\……\SLL\SLL_.cpp 6
错误 C2143 语法错误: 缺少“;”(在“<”的前面) SLL D:\……\SLL\SLL_.cpp 6
错误 C2059 语法错误:“<” SLL D:\……\SLL\SLL_.cpp 20
错误 C2039 "getdata": 不是 "`global namespace'" 的成员 SLL D:\……\SLL\SLL_.cpp 6
错误 C2143 语法错误: 缺少“;”(在“{”的前面) SLL D:\……\SLL\SLL_.cpp 6
错误 C2447 “{”: 缺少函数标题(是否是老式的形式表?) SLL D:\……\SLL\SLL_.cpp 6
cpp文件每一个定义的函数都有这几个错误
我的解答思路和尝试过的方法
一开始我只是去Microsoft的官方文档里去看错误分析,结果一如既往的一头雾水
然后在CSDN里查询了很多关于模板类的编写规范,都未能找到相关问题的描述。
我尝试过在预编译命令里更改include文件,修改了类成员函数为模板函数。但是编辑器反而报错
h头文件修改
template<typename F> D* getdata();
template<typename F> element2& operator--(int);
template<typename F> element2& operator++(int);
//其它函数类似
cpp源文件修改
template <class D>template<typename F> D* element2<D>:: getdata() {
return data;
}
……
//其它函数类似
template <typename D>template <typename F>
bool SLL<D>:: add_element2(const D* any, const element2<D>* laster)
{
element2<D>* adder = new element2(any);
……
}
错误(活动) E0864 element2 不是模板 SLL D:\……\SLL\SLL_.cpp 20
错误(活动) E0864 element2 不是模板 SLL D:\……\SLL\SLL_.cpp 24
并且报错不稳定,当我返回头文件用光标查看element2的类定义,再返回源文件中时,偶尔又会显示为另一个错误
错误(活动) E0147 声明与 函数模板 "bool SLL::add_element2(const D *any, const *laster)" (已声明 所在行数:38) 不兼容 SLL D:\……\SLL\SLL_.cpp 38
一番搜索过后,我发现在头文件的element2的声明里,element2似乎并没有被识别成模板类
我发现似乎第一个模板似乎都是无效的,于是我在最开头,又加了一个没用的类
#ifndef element2,SLL,OSLL
template<typename D>class element {};
//定义第二元素类element2,只能被SLL等类创建和销毁,重载了后置自增和自减运算符
template <typename D>class element2
{
D* data;
element2<D>* last;
这样编辑器不报错了,但是,生成时仍然会报原来的错误
错误 C2988 不可识别的模板声明/定义 SLL D:\……\SLL\SLL_.cpp 20
错误 C2143 语法错误: 缺少“;”(在“<”的前面) SLL D:\……\SLL\SLL_.cpp 20
错误 C2059 语法错误:“<” SLL D:\……\SLL\SLL_.cpp 20
错误 C2039 "getdata": 不是 "`global namespace'" 的成员 SLL D:\……\SLL\SLL_.cpp 20
错误 C2143 语法错误: 缺少“;”(在“{”的前面) SLL D:\……\SLL\SLL_.cpp 20
错误 C2447 “{”: 缺少函数标题(是否是老式的形式表?) SLL D:\……\SLL\SLL_.cpp 20