C++使用模板时出现duplicate symbol重复符号链接错误问题咨询
报错原因及解决方法
根本原因
你代码里针对Example类型的swap全特化函数定义放在了头文件中,触发了普通函数的多编译单元重复定义规则:
- 泛型主模板
template <typename T> void swap(T& a, T& b)定义放在头文件是合法的,编译器对隐式实例化的模板函数会生成弱符号,链接阶段自动去重。 - 但全特化的模板函数已经不属于模板范畴,本质是一个普通的非模板函数,和你写的
operator<<等普通函数性质完全一致。如果将它的定义放在头文件中,被多个.cpp文件包含后,每个编译单元都会生成一份独立的函数实例,链接时就会报重复符号错误。
你拆分文件前所有代码都在同一个编译单元,所以不会触发该问题;拆分后main.cpp和whatever.cpp都引入了头文件中的全特化swap定义,就导致两个目标文件都存在该符号,链接冲突。
解决方法
二选一即可:
- 给头文件中的全特化
swap函数添加inline修饰,允许定义在多编译单元重复出现,链接器会自动合并:
// whatever.hpp 中修改为 template <> inline void swap<Example>(Example &a, Example &b) { int n = a.getN(); a.setN(b.getN()); b.setN(n); }
- 将全特化
swap的定义移到whatever.cpp中,仅在头文件保留声明:
// whatever.hpp 中仅保留声明 template <> void swap<Example>(Example &a, Example &b); // whatever.cpp 中添加实现 template <> void swap<Example>(Example &a, Example &b) { int n = a.getN(); a.setN(b.getN()); b.setN(n); }
内容的提问来源于stack exchange,提问作者kubo
相关产品推荐
相关产品推荐

