使用模板时模板的定义应该放到头文件

12 篇文章 0 订阅

在使用函数模板之前,编译器必须看到不仅仅是一个声明,通常编译器需要完整的函数模板定义。换句话说,如果你在头文件中定义了一个模板,那么这个头文件必须包含该函数模板的主体。

假设需要在许多项目之间共用某个函数foo。通常情况下,会将函数声明放在一个头文件中,比如common.hpp,并将完整的定义放在一个单独的源文件中,比如common.cpp
然而,当该函数为函数模板时,通常会将定义放在头文件中。这是为了让编译器从模板创建具体的函数,比如foo<int>foo<long>,它需要函数模板的主体。

错误示例:
common.hpp

#pragma once

template<class T>
T my_max(T a, T b);

common.cpp

#include "common.hpp"

template<class T>
T my_max(T a, T b){
    return a > b? a: b;
}

main.cpp

// g++ -I. main.cpp common.cpp -O2
#include <iostream>
#include "common.hpp"

int main() {
    std::cout << my_max<long>(12, 23U) << std::endl;
    std::cout << my_max<float>(42.f, 23U) << std::endl;
}

使用指令g++ -I. main.cpp common.cpp -O2编译时提示如下错误:

/usr/bin/ld: /tmp/ccfkfBWe.o: in function `main':
main.cpp:(.text.startup+0x14): undefined reference to `long my_max<long>(long, long)'
/usr/bin/ld: main.cpp:(.text.startup+0x3c): undefined reference to `float my_max<float>(float, float)'
collect2: error: ld returned 1 exit status

如上错误就是因为没有用模板生成对应的函数定义,报未定义的引用的错误。

正确示例:

common.hpp

#pragma once

template<class T>
T my_max(T a, T b){
    return a > b ? a: b;
}

main.cpp

// g++ -I. main.cpp -O2
#include <iostream>
#include "common.hpp"

int main() {
    std::cout << my_max<long>(12, 23U) << std::endl;      // 23
    std::cout << my_max<float>(42.f, 23U) << std::endl;   // 42
}

通过在编译指令中加--save-temps验证汇编代码中确实存在longfloat两个版本的函数实现。
g++ -I. main.cpp --save-temps -O2

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值