如何在模板类声明主体之外实现成员函数?

时间:2019-01-30 12:41:29

标签: c++ templates

我有一个模板类,该模板类具有泛型形式的大型成员函数,因此通读它并不容易。 我决定将此函数移到类主体之外,并在与“ .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;
};

2 个答案:

答案 0 :(得分:2)

有两种方法可以解决此问题:

  • 显式实例化
  • 包含模型
  • 分离模型

显式实例化的工作方式与您的模板专业化示例相似:

template my_class<size_t>::my_class();

显式实例化类型为size_t的my_class<T>的构造函数。

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

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

export template <typename T>
struct C {};

答案 1 :(得分:1)

您有

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

这里的问题是没有名为ClassC class ,您只有一个带有该名称的 template 。要获得完整的课程,您需要ClassC<T>

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

就像错误消息中所述,您需要包括模板参数。

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