【发布时间】:2014-10-01 01:12:54
【问题描述】:
我对 C++ 比较陌生,所以我的问题可能有一个简单的答案;但是,我不知道为什么我的代码在我认为应该工作的时候不能工作。示例代码如下。
//a.h
#ifndef A
#define A
template<class T>
class a{
public:
a();
private:
T str;
};
#include "a.cpp"
#endif
//a.cpp
//#ifdef A
#include "a.h"
using namespace std;
template<class T>
a<T>::a(){
str = 'a';
}
//#endif
//driver.cpp
#include"a.h"
#include <string>
using namespace std;
void main(){
a<string> object;
}
我一直在网上阅读有关如何在包含模板时避免错误的信息。其中之一就是我想在这里实现的目标:在a.h 中拥有#include "a.cpp"。但是,我查看的示例仍然在a.cpp 中使用#include "a.h",如示例代码所示。但是,我收到了 function template has already been defined 错误。我发现在 a.cpp 中使用 #ifdef A 并注释掉 #include "a.h" 将帮助我摆脱这个重新定义错误。但我想了解发生了什么。 a.h 中的包含守卫不应该已经处理了重新定义吗?
【问题讨论】:
-
只需将所有模板内容放在头文件中就可以了。
-
一般来说,包含 .cpp 文件是自找麻烦。您应该通过单独编译每个 .cpp 文件来构建您的程序,一次且仅一次。
-
@NeilKirk 说了什么,here's why。
-
就像大家说的,你应该重新排列东西。然而,这仍然没有回答这个问题:你为什么要重新定义?我的猜测是您正在尝试编译 a.cpp——而不仅仅是 driver.cpp。如果您尝试编译 a.cpp,它将包含 a.h,其中包含 a.cpp(a
::a() 的第一个定义),然后将在之后再次定义 a ::a() a.h. 的包含您注释掉的“#ifdef A”删除了第一个定义。 -
@ChrisA。我看不出我的代码与您在链接中提供的第一个解决方案有何根本不同。我注意到的区别是
include guards、tpp而不是cpp,以及cpp 文件中缺少的#include .h。我尝试根据上面提到的最后一个差异进行更改,但我遇到了更多错误,我认为这是由于实现文件不知道声明。至于排除include guard,我会得到循环依赖。你能更具体地说明我做错了什么吗?
标签: c++ templates include-guards