C++模板函数踩坑

报错重定义

  • 解决方式:inline 函数( inline 标记一个函数时,允许编译单元中有相同签名的实体,最后链接时只保留一个。这样你就可以将函数的实现写在头文件里,而不用担心冲突了。而如果没有 inline 标记的函数,你把函数体写在头文件里,该头文件被多个源文件包含并使用时,链接时就会冲突。)

  • main.cpp
#include <iostream>
#include <string>
#include "tempalate.h"

int main() {
	S1<int>(2.1);
	S1<bool>(2.1);
	S1<float>(2.1);
	S1<double>(2.1);
	std::cout << '\n';
	int* p = new int(1);
	std::cout << "getTypeName(p): " << getTypeName(p) << '\n';
	std::cout << "getTypeName2(p): " << getTypeName2(p) << '\n';
	std::cout << '\n';
	delete p;
	p = nullptr;
}
输出:
special int !
bool!
float!
double!

getTypeName(p): int pointer
getTypeName2(p): pointer

special int !
  • tempalate.h
#pragma once
#include <iostream>
#include <typeinfo>
using namespace std;

template<typename T>
inline void S1(T num)
{
	cout << typeid(T).name() << "!" << endl;
	return;
}

template<>
inline void S1(int num)
{
	cout << "special int !" << endl;
	return;
}

template<typename T>            // (1) - 主模板
inline std::string getTypeName(T)
{
	return "unknown";
}

template<typename T>            // (2) - 重载自 (1) 的主模板
inline std::string getTypeName(T*)
{
	return "pointer";
}

template<>                      // (3) - (2) 的显式特例化
inline std::string getTypeName(int*)
{
	return "int pointer";
}

// getTypeName2

template<typename T>            // (4) - 主模板
inline std::string getTypeName2(T) {
	return "unknown";
}

template<>                      // (5) - (4) 的显式特例化
inline std::string getTypeName2(int*) {
	return "int pointer";
}

template<typename T>            // (6) - 重载自 (4) 的主模板
inline std::string getTypeName2(T*) {
	return "pointer";
}

拓展

  • 类函数默认内联
  • 函数模板的特例化不参与重载
  • 由于模板不是函数,只是一些C++编译器指令,说明了如何生成类和成员函数定义,无法单独编译成obj文件,因此不能将模板成员函数放在独立的实现文件中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值