C++ 模板类编译“;在‘之前需要构造函数、析构函数或类型转换<’;代币;错误
我在编译模板类时遇到问题。这是我的名单C++ 模板类编译“;在‘之前需要构造函数、析构函数或类型转换<’;代币;错误,c++,templates,C++,Templates,我在编译模板类时遇到问题。这是我的名单 using namespace std; template <class T> List<T>::List() { length = 0; } template <class T> List<T>::~List() { } template <class T> List<T> & List<T>::operator=(const List<T
using namespace std;
template <class T>
List<T>::List()
{
length = 0;
}
template <class T>
List<T>::~List()
{
}
template <class T>
List<T> & List<T>::operator=(const List<T> & rhs)
{
List<T> hha;
return hha;
}
template <class T>
int List<T>::size()
{
return length;
}
使用名称空间std;
模板
列表::列表()
{
长度=0;
}
模板
列表::~List()
{
}
模板
列表和列表::运算符=(常量列表和rhs)
{
列出hha;
返回hha;
}
模板
int List::size()
{
返回长度;
}
这是我的名单
#ifndef _LIST_H_
#define _LIST_H_
#include <iterator>
#include <ostream>
using namespace std;
template <class T>
class List
{
private:
class ListNode
{
public:
ListNode();
ListNode(const T element);
ListNode *next;
T data;
};
public:
// big3
List();
~List();
List<T> & operator=(const List<T> & rhs);
int size();
bool empty();
void print(ostream & os) const;
private:
ListNode * head;
ListNode * tail;
int length;
};
#include "list.cpp"
#endif
\ifndef\u列表_
#定义列表_
#包括
#包括
使用名称空间std;
模板
班级名单
{
私人:
类ListNode
{
公众:
ListNode();
ListNode(常量T元素);
ListNode*下一步;
T数据;
};
公众:
//大3
List();
~List();
列表和运算符=(常量列表和rhs);
int size();
bool empty();
无效打印(ostream&os)常数;
私人:
ListNode*头;
ListNode*尾部;
整数长度;
};
#包括“list.cpp”
#恩迪夫
当我运行g++list.cpp时
我会犯错误
在“模板实现进入标头之前,需要构造函数、析构函数或类型转换
这有点像黑客,但它是如何做到的。模板实现在标题中
这有点像黑客,但它是如何做到的。因为
list.hpp
没有#在list.cpp
中包含d,当您尝试编译list.cpp
时,编译器不知道该标头中的模板定义,因为list.hpp
无法获取#在list.cpp
中包含d,当您尝试编译list.cpp
时,编译器不知道该标头中的模板定义。您当前遇到的问题是list.cpp
不包括您list.h
:编译器会看到一些尚未声明的内容的定义。您可以通过在文件顶部包含list.h
来解决此问题:
#include "list.h"
...
但是,这将从本质上导致一个问题:如果您真的想将列表
用于某种类型,编译器将需要查看使用类模板的模板定义。也就是说,通常您将在头文件中实现模板。另一种方法是在实现文件中实现模板,并显式地实例化要与之一起使用的类型。这对于某些模板来说是相当合理的,但是对于用于未知数量类型的模板来说,这是不实际的
BTW,您使用的名称是不允许触摸的:从下划线开始的名称后面是大写字母,这是为C++实现的,即编译器和标准库。在任何地方使用两个连续下划线的名称也会被保留。
您当前遇到的问题是您列表。cpp
不包括您列表。h
:编译器会看到一些尚未声明的定义。您可以通过在文件顶部包含list.h
来解决此问题:
#include "list.h"
...
但是,这将从本质上导致一个问题:如果您真的想将列表
用于某种类型,编译器将需要查看使用类模板的模板定义。也就是说,通常您将在头文件中实现模板。另一种方法是在实现文件中实现模板,并显式地实例化要与之一起使用的类型。这对于某些模板来说是相当合理的,但是对于用于未知数量类型的模板来说,这是不实际的
BTW,您使用的名称是不允许触摸的:从下划线开始的名称后面是大写字母,这是为C++实现的,即编译器和标准库。在任何位置使用两个连续下划线的名称也被保留。
您可以编译定义列表成员函数的list.cpp
。但它不包含模板类声明-即在标题中
我看到您在列表标题中包含了cpp。如果在其他cpp文件中包含列表头,并确保不会将list.cpp
作为单独的编译单元进行编译,则这将起到一定的作用
我的意思是,即文件main.cpp:
#include "list.h"
int main()
{}
然后用g++main.cpp
编译此文件
通常,在完全使用模板时,您只希望避免使用cpp文件。只需在标题中填入所有内容,并将其包括在内。或者,我至少会将您的list.cpp
重命名为list.impl
或其他名称。通过这种方式,人们可能不太愿意直接编译该文件。您可以编译定义列表成员函数的list.cpp
。但它不包含模板类声明-即在标题中
我看到您在列表标题中包含了cpp。如果在其他cpp文件中包含列表头,并确保不会将list.cpp
作为单独的编译单元进行编译,则这将起到一定的作用
我的意思是,即文件main.cpp:
#include "list.h"
int main()
{}
然后用g++main.cpp
编译此文件
通常,在完全使用模板时,您只希望避免使用cpp文件。只需在标题中填入所有内容,并将其包括在内。或者,我至少会将您的list.cpp
重命名为list.impl
或其他名称。通过这种方式,人们可能不太愿意直接尝试编译该文件。在“一点”之前的许多可能重复的预期构造函数、析构函数或类型转换中,在“之前的许多可能重复的预期构造函数、析构函数或类型转换中,在哪一个上”这一部分让我过了一天:我不知道我的朋友在哪里