crystalloid_iron 2022-10-22 11:01 采纳率: 0%
浏览 38

C++模板类编译时出现奇怪的未知错误,如何解决?

问题遇到的现象和发生背景

在用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似乎并没有被识别成模板类

光标在element2后面时


光标在SLL类里时


我发现似乎第一个模板似乎都是无效的,于是我在最开头,又加了一个没用的类

#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

希望各位网友帮忙解答:目前编译过程中遇到的问题原因、及解决方法,万分感谢!
  • 写回答

1条回答 默认 最新

  • 真相重于对错 2022-10-22 11:32
    关注

    c++ 编译器不允许分离

    评论

报告相同问题?

问题事件

  • 修改了问题 10月22日
  • 创建了问题 10月22日

悬赏问题

  • ¥15 bat批处理,关于数据复制问题
  • ¥50 同步两个不同结果的array中某些属性
  • ¥15 悬赏15远程操控解决问题
  • ¥15 CST复制的模型无法单独修改参数?
  • ¥15 前端页面想做个定时任务,但是使用requestAnimationFrame,setinterval和settimeout都不行
  • ¥15 根据以下文字信息,做EA模型图
  • ¥15 删除虚拟显示器驱动 删除所有 Xorg 配置文件 删除显示器缓存文件 重启系统 可是依旧无法退出虚拟显示器
  • ¥15 vscode程序一直报同样的错,如何解决?
  • ¥15 关于使用unity中遇到的问题
  • ¥15 开放世界如何写线性关卡的用例(类似原神)