【问题标题】:c++ template and include guards [duplicate]c ++模板并包含警卫[重复]
【发布时间】: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 guardstpp 而不是cpp,以及cpp 文件中缺少的#include .h。我尝试根据上面提到的最后一个差异进行更改,但我遇到了更多错误,我认为这是由于实现文件不知道声明。至于排除include guard,我会得到循环依赖。你能更具体地说明我做错了什么吗?

标签: c++ templates include-guards


【解决方案1】:

简短的回答:如果实现与声明不在同一个标​​头中,则编译器尝试实例化模板时将无法访问它。

【讨论】:

    【解决方案2】:

    这不是将模板实现与模板声明分开的方法。您没有在 .h 文件中包含 .cpp 文件。相反,您只需将 .cpp 文件添加到您的项目文件或 make 文件中,以便像所有其他文件一样编译它。然后使用Explicit Template Instantiation 来避免链接错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      相关资源
      最近更新 更多