模板类编译“期望构造函数,析构函数或'<'令牌之前的类型转换”错误

时间:2012-02-26 21:37:36

标签: c++ templates

我在编译模板类时遇到问题。这是我的list.cpp

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;
}

这是我的list.h

#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

当我运行g ++ list.cpp

我收到错误

在'&lt;'标记

之前的预期构造函数,析构函数或类型转换

用于构造函数,析构函数和运算符的定义......

我不知道什么是错的

4 个答案:

答案 0 :(得分:2)

模板实现在标题中。

这有点像黑客,但它是如何完成的。

答案 1 :(得分:1)

您目前遇到的问题是list.cpp不包括list.h:编译器会看到一些尚未声明的事物的定义。您可以通过在文件顶部添加list.h来解决此问题:

#include "list.h"
...

然而,这实际上会导致出现问题:如果您确实想要使用某种类型的List<T>,编译器将需要查看使用类模板的模板定义。也就是说,通常您将在头文件中实现模板。该替代方法是在实现文件中实现模板,并显式实例化它要使用的类型。对于某些模板来说这是非常合理的,但对于那些用于未知数量类型的东西,这是不切实际的。

顺便说一句,您使用的是不允许触摸的名称:以下划线后跟大写字母开头的名称保留给C ++实现,即编译器和标准库。在任何地方使用两个连续下划线的名称也是保留的。

答案 2 :(得分:0)

由于list.hpp未在#include中获得list.cpp d,因此当您尝试编译list.cpp时,编译器不知道该标头中的模板定义。

答案 3 :(得分:0)

编译list.cpp,定义列表成员函数。但它不包含模板类声明 - 即在标题中。

我看到你在列表标题中包含cpp。如果在其他cpp文件中包含列表标题,并确保list.cpp不会编译为单独的编译单元,这将有用。

我的意思是文件main.cpp:

#include "list.h"
int main()
{}

然后使用g++ main.cpp编译它。

通常,您只想在完全使用模板时避免使用cpp文件。只需填写标题中的所有内容即可。或者,我至少会将您的list.cpp重命名为list.impl或其他名称。通过这种方式,人们可能不太愿意直接尝试编译该文件。

相关问题