如何将类模板的成员函数定义在单独*.cpp文件而非类声明头文件
报错原因
C++模板在被调用时,编译器需要看到完整的实现代码才能生成对应具体类型的实例化版本。你将模板成员函数的实现放在独立的.cpp文件中时,其他引用该头文件的编译单元只能看到模板声明,无法获取实现代码完成实例化,链接阶段就会抛出undefined reference错误。
可行解决方法
方法1:显式实例化所有需要用到的模板类型
如果你的模板只会用到有限的几个固定参数类型,可以直接在实现的.cpp文件末尾添加显式实例化声明,编译器会在编译这个.cpp时生成对应类型的实例,链接时就能正常找到:
// cpp文件原有实现代码 template <class T> A<T>::A(){} template <class T> T A<T>::get_data() { return data; } // 末尾添加显式实例化,示例为需要用到int和std::string两种类型的A的场景 template class A<int>; template class A<std::string>;
- 优点:模板实现完全保留在.cpp文件中,头文件仅暴露声明,编译速度更快
- 缺点:需要提前预知所有要用到的模板参数类型,不支持外部用户传入自定义类型使用模板
方法2:分离声明与实现文件后在头文件引入实现
如果你需要支持任意类型的模板参数,可以将实现代码放在独立的.ipp/.hpp后缀的头文件中,在类声明的头文件末尾引入该实现文件:
// class.h 头文件内容 template <class T> class A{ public: A(); T get_data(); private: T data; }; // 头文件末尾引入实现文件 #include "A.ipp"
// A.ipp 实现文件内容 template <class T> A<T>::A(){} template <class T> T A<T>::get_data() { return data; }
- 优点:实现了代码结构层面的声明与实现分离,支持任意类型的模板实例化
- 缺点:本质上实现代码还是暴露给了所有引用头文件的编译单元,修改实现后所有引用该头文件的代码都需要重新编译
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

