【问题标题】:How to implement a member function outside of a template class declaration body? [duplicate]如何在模板类声明体之外实现成员函数? [复制]
【发布时间】:2019-06-23 18:03:59
【问题描述】:

我有一个模板类,它有一个泛型形式的大成员函数,所以通读它不是很容易。 我决定将此函数移到类主体之外,并在与“.hpp”同名的“.cpp”文件中实现它,但我无法通过编译。 如果我以专用形式而不是通用形式实现它,则可以编译/链接它,即使它也保存在“*.cpp”文件中。

代码如下:

ClassC.hpp:

#pragma once
template <typename T>
class ClassC {
public:
   ClassC( T* p ) : d( p ) {};
   void show();
private:
   T* d;
};

ClassC.cpp

#include <iostream>
#include "ClassC.hpp"
#include "ClassD.hpp"
using namespace std;

// this is a specialized version, and can be compiled/linked.
template <>
void ClassC<ClassD>::show() {
   cout << "This is a specialized ClassC." << endl;
};

// this is my generic version, and can not be compiled.
template <typename T>
void ClassC::show() {
     cout << "This is a generic ClassC." << endl;
};
/* */

ClassD.hpp

#pragma once
#include "ClassC.hpp"
class ClassD {
public:
   ClassD(): c( this ) {};
   void show();
private:
   ClassC<ClassD> c;
};

ClassD.cpp

#include <iostream>
#include "ClassD.hpp"
using namespace std;
void ClassD::show() {
   c.show();
   cout << "This is ClassD" << endl;
};

main.cpp

#include "ClassD.hpp"
int main() {
   ClassD d;
   d.show();
   return 0;
};

【问题讨论】:

  • 右侧有相关问题列表。看看那些,尤其是名为Why can templates only be implemented in the header file?的那个。
  • 如果您在特定问题上需要帮助,那么您需要告诉我们具体问题是什么。你得到什么错误?如果你不能具体,那我们就不能给出具体的答案。也请阅读how to ask good questions,以及this question checklist
  • 当我添加通用版本时,我评论了专业。
  • path/of/the/ClassC.cpp:16:6: error: ‘template class ClassC’ used without template parameters

标签: c++ templates


【解决方案1】:

有几种方法可以解决这个问题:

  • 显式实例化
  • 包容性模型
  • 分离模型

显式实例化与您的模板专业化示例类似:

template my_class<size_t>::my_class();

为 size_t 类型显式实例化 my_class&lt;T&gt; 的构造函数。

包容性模型 代码要么写在 .h 文件中,这是处理此问题的一种非常常见的方法,要么我们在声明该模板的头文件中包含模板的定义,因此: #include "my_file.cpp".

分离模型 使用关键字export。但是,我几乎从未使用过它,因为它的执行速度很慢。

export template <typename T>
struct C {};

【讨论】:

  • 非常感谢!我将使用您提到的第一个解决方案,因为我担心如果“my_file.cpp”需要包含在多个地方,第二个可能会导致一些“符号重新定义”问题。至于第三个,在大多数现代编译器和最新的 c++ 标准中,关键字“export”似乎已被标记为已弃用。如果我理解正确的话,第一个解决方案中的“实例化”一词可能被理解为“专业化”。我对吗?不是为了修改,只是为了理解。
  • 这个问题描述了不同之处:stackoverflow.com/questions/3914642/…
【解决方案2】:

你有例如

template <typename T>
void ClassC::show() {
     cout << "This is a generic ClassC." << endl;
};

这里的问题是没有名为ClassC,您只有一个具有该名称的模板。要获得完整的课程,您需要ClassC&lt;T&gt;

template <typename T>
void ClassC<T>::show() {
     cout << "This is a generic ClassC." << endl;
};

如错误消息所述,您需要包含模板参数。

当然不要忘记阅读Why can templates only be implemented in the header file?,因为这将回答您的下一个问题。

【讨论】:

  • 非常感谢。抱歉稍后再回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
相关资源
最近更新 更多