从.h(获取错误)定义.cpp中的模板函数

时间:2022-07-10 17:01:44

Part of the header file dlist.h is defined as:

部分头文件dlist。h的定义是:

#ifndef __DLIST_H__
#define __DLIST_H__
#include <iostream>

class emptyList {};

template <typename T>
class Dlist {
 public:
    bool isEmpty() const;

 private:
    struct node {
    node   *next;
    node   *prev;
    T      *o;
    };

    node   *first; // The pointer to the first node (NULL if none)
    node   *last;  // The pointer to the last node (NULL if none)
};

#include "dlist.cpp"
#endif

When I create a dlist.cpp file like this:

当我创建一个dlist。cpp文件如下:

#include "dlist.h"

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

I get the error message at line 4: redefinition of 'bool Dlist::isEmpty() const'

我在第4行得到错误消息:“bool Dlist::isEmpty() const”的重新定义

If I remove the #include "dlist.h" I get the error at line 4: expected initializer before '<' token

如果我删除了#include“dlist”。“我在第4行得到了错误:预期初始化器在‘<'令牌之前。

Any help here? Is there something I'm doing wrong that's not allowing me to just define my functions from the dlist.h file? Thank you.

任何帮助吗?我做错了什么,不允许我从dlist中定义函数。h文件?谢谢你!

5 个解决方案

#1


7  

You have to put the implementation of the class template's member functions in the header file or in a file included by the header. The compiler needs access to this code in order to instantiate templates for any given type T.

您必须将类模板的成员函数的实现放在头文件中,或者在头文件中包含的文件中。编译器需要访问该代码,以实例化任何给定类型T的模板。

In your case, the problem seems to be that you are including the header in the .cpp and vice versa. If you really want to keep declaration and implementation in separate files, I suggest changing the implementation's suffix from .cpp to something else, e.g. .icpp. Some build systems might try to compile an object file out of anything with a .cpp suffix, and this would also result in error.

在您的案例中,问题似乎在于您包含了.cpp中的头,反之亦然。如果您真的希望在单独的文件中保持声明和实现,我建议将实现的后缀从.cpp更改为其他东西,例如:.icpp。一些构建系统可能尝试用.cpp后缀来编译一个对象文件,这也会导致错误。

  1. Remove #include "dlist.h" from dlist.cpp.
  2. 删除#包括“dlist。从dlist.cpp h”。
  3. (optional) rename dlist.cpp to something like dlist.icpp. Why? Because many build systems automatically compile any file ending in .cpp into an object file. And many programmers assume that a .cpp file will be compiled into an object file.
  4. (可选)重命名dlist。cpp,类似于dlist.icpp。为什么?因为许多构建系统会自动地编译任何以.cpp结尾的文件到一个对象文件中。许多程序员认为,.cpp文件将被编译成一个对象文件。
  5. (only if step 2 taken) include the re-named dlist.icpp in dlist.h, as is currently done for dlis.cpp.
  6. (仅当第2步采取)包括重新命名的dlist。icpp dlist。就像目前dlis.cpp所做的那样。

#2


2  

The header file is defined for me, I'm not allowed to change it in any way

头文件是为我定义的,我不允许以任何方式改变它。

Then you'll need to remove the #include "dlist.h" directive from the .cpp (because you're already in dlist.h, and thus creating a cyclic dependency), thus making everything completely backwards, because the header you were given is fscking stupid!

然后您需要删除#include“dlist”。来自.cpp的指令(因为你已经在dlist中了)。因此,创建一个循环依赖项),从而使一切完全向后,因为您所得到的标题是fscking愚蠢!

A .cpp should never be #included. Typically, if one must split template-related definitions into their own file, it should have some other extension. I strongly recommend you talk to the person who has emplaced this mandate on you and explain that their header is silly, confusing and non-conventional.

A .cpp不应该包括在内。通常,如果必须将与模板相关的定义分解为自己的文件,那么它应该具有其他扩展。我强烈建议你和那些把这个任务交给你的人谈谈,并解释说他们的头头是愚蠢的,令人困惑的,而且是不常规的。

#3


1  

Instead of using #include "dlist.cpp" in your header file, move the function definition into dlist.h.

而不是使用#include“dlist”。在头文件中,将函数定义移动到dlist.h中。

#4


1  

Why do you include .cpp file in .h file? In 99% of cases you shouldn't do that.

为什么在.h文件中包含.cpp文件?99%的情况下你不应该这样做。

Just add your code

把你的代码

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

Instead of .cpp file include directive.

而不是。cpp文件包括指令。

#5


0  

Remove the #include "dlist.h" and do not compile dlist.cpp itself.

删除dlist # include”。并且不要编译dlist。cpp本身。

You can also use something like this:

你也可以这样使用:

because dlist.h includes dlist.cpp and defines __DLIST_H__:

因为dlist。h包括dlist。cpp和定义__DLIST_H__:

#define __DLIST_H__

You can modify the dlist.cpp to

您可以修改dlist。cpp来

#ifdef __DLIST_H__

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

#endif

This way you don't get a compiler error if you try to compile dlist.cpp. But I agee with the other answers it is better not to name this file .cpp.

这样,如果试图编译dlist.cpp,就不会得到编译器错误。但是,我和其他的答案一样,最好不要给这个文件命名。

#1


7  

You have to put the implementation of the class template's member functions in the header file or in a file included by the header. The compiler needs access to this code in order to instantiate templates for any given type T.

您必须将类模板的成员函数的实现放在头文件中,或者在头文件中包含的文件中。编译器需要访问该代码,以实例化任何给定类型T的模板。

In your case, the problem seems to be that you are including the header in the .cpp and vice versa. If you really want to keep declaration and implementation in separate files, I suggest changing the implementation's suffix from .cpp to something else, e.g. .icpp. Some build systems might try to compile an object file out of anything with a .cpp suffix, and this would also result in error.

在您的案例中,问题似乎在于您包含了.cpp中的头,反之亦然。如果您真的希望在单独的文件中保持声明和实现,我建议将实现的后缀从.cpp更改为其他东西,例如:.icpp。一些构建系统可能尝试用.cpp后缀来编译一个对象文件,这也会导致错误。

  1. Remove #include "dlist.h" from dlist.cpp.
  2. 删除#包括“dlist。从dlist.cpp h”。
  3. (optional) rename dlist.cpp to something like dlist.icpp. Why? Because many build systems automatically compile any file ending in .cpp into an object file. And many programmers assume that a .cpp file will be compiled into an object file.
  4. (可选)重命名dlist。cpp,类似于dlist.icpp。为什么?因为许多构建系统会自动地编译任何以.cpp结尾的文件到一个对象文件中。许多程序员认为,.cpp文件将被编译成一个对象文件。
  5. (only if step 2 taken) include the re-named dlist.icpp in dlist.h, as is currently done for dlis.cpp.
  6. (仅当第2步采取)包括重新命名的dlist。icpp dlist。就像目前dlis.cpp所做的那样。

#2


2  

The header file is defined for me, I'm not allowed to change it in any way

头文件是为我定义的,我不允许以任何方式改变它。

Then you'll need to remove the #include "dlist.h" directive from the .cpp (because you're already in dlist.h, and thus creating a cyclic dependency), thus making everything completely backwards, because the header you were given is fscking stupid!

然后您需要删除#include“dlist”。来自.cpp的指令(因为你已经在dlist中了)。因此,创建一个循环依赖项),从而使一切完全向后,因为您所得到的标题是fscking愚蠢!

A .cpp should never be #included. Typically, if one must split template-related definitions into their own file, it should have some other extension. I strongly recommend you talk to the person who has emplaced this mandate on you and explain that their header is silly, confusing and non-conventional.

A .cpp不应该包括在内。通常,如果必须将与模板相关的定义分解为自己的文件,那么它应该具有其他扩展。我强烈建议你和那些把这个任务交给你的人谈谈,并解释说他们的头头是愚蠢的,令人困惑的,而且是不常规的。

#3


1  

Instead of using #include "dlist.cpp" in your header file, move the function definition into dlist.h.

而不是使用#include“dlist”。在头文件中,将函数定义移动到dlist.h中。

#4


1  

Why do you include .cpp file in .h file? In 99% of cases you shouldn't do that.

为什么在.h文件中包含.cpp文件?99%的情况下你不应该这样做。

Just add your code

把你的代码

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

Instead of .cpp file include directive.

而不是。cpp文件包括指令。

#5


0  

Remove the #include "dlist.h" and do not compile dlist.cpp itself.

删除dlist # include”。并且不要编译dlist。cpp本身。

You can also use something like this:

你也可以这样使用:

because dlist.h includes dlist.cpp and defines __DLIST_H__:

因为dlist。h包括dlist。cpp和定义__DLIST_H__:

#define __DLIST_H__

You can modify the dlist.cpp to

您可以修改dlist。cpp来

#ifdef __DLIST_H__

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

#endif

This way you don't get a compiler error if you try to compile dlist.cpp. But I agee with the other answers it is better not to name this file .cpp.

这样,如果试图编译dlist.cpp,就不会得到编译器错误。但是,我和其他的答案一样,最好不要给这个文件命名。