当前位置: 首页 > web >正文

C++:模板初阶

引入:

模板的发明对于泛型编程起了很大的作用,因为在实践的过程中我们发现,很多不同类型的功能类似的函数,其实现逻辑是类似的。

1.函数模板

语法:

关键字:template

写法1:

template<class T>

写法2:

template<typename T>

如果有多个参数,就用逗号分隔

template<typename T1,typename T2>

模板参数定义的是类型,typename后面的名字随便取,可以是T1,T2,也可以是其它的。

使用:

template<class T>//把这一句加在函数前面就行,不能用';'分隔
T f(T a,T b)
{    return a+b;
}

T的类型不同,调用的是不同的函数。

f<int>(1,2);
f<double>(1.0,2.0);

所以,模板的作用其实是编译器用模板生成实例化函数,不过函数的模板可以不用显式实例化

f(1,2);
f(1.0,2.0);

如果类型不匹配,编译会报错

1. 模板参数数量不匹配

如果模板定义时只有一个类型参数,但在实例化模板时提供了两个类型参数,这会导致编译错误。例如:

template <typename T>
void print(T value) {std::cout << value << std::endl;
}int main() {print<int, double>(10); // 错误:模板定义只有一个类型参数,但这里提供了两个return 0;
}

编译器会报错,因为print模板只接受一个类型参数,而这里却传入了两个。

2. 模板参数类型不匹配

如果模板定义时的类型参数与实际传入的类型不匹配,也可能导致编译错误。不过,这种情况通常发生在模板函数的参数类型与模板参数不一致时。例如:

template <typename T>
void add(T a, T b) {std::cout << a + b << std::endl;
}int main() {add(10, 20.5); // 错误:模板参数类型不匹配return 0;
}

这里,add模板函数的两个参数类型必须相同,但传入的10是int类型,而20.5double类型,因此编译器会报错。

解决方案:
add(10, (int)20.5);
//或者这样
add((double)10, 20.5);

3. 模板特化时类型不匹配

如果对模板进行了特化,但特化的类型与实际使用的类型不匹配,也会导致编译错误。例如:

template <typename T>
void print(T value) {std::cout << value << std::endl;
}template <>
void print<int>(int value) {std::cout << "Specialized for int: " << value << std::endl;
}int main() {print<double>(3.14); // 错误:特化只针对int,而这里使用了doublereturn 0;
}

逻辑相似的函数与函数模板可以同时存在吗?

template<class T>
T f(T a,T b)
{    return a+b;
}int f(int a,int b)
{return a+b;
}

事实上是可以的,在C++中,模板函数和普通函数可以同时存在,即使它们的签名在某些情况下完全一致,也不会导致编译错误。原因在于C++的函数重载规则和模板实例化的机制。

1.普通函数的优先级比模板函数要高

2.模板函数只有在被调用时才会被实例化。在实例化之前,编译器不会检查模板函数和普通函数之间的冲突。

3.如果模板函数实例化后与普通函数完全相同,模板函数会被“覆盖”,其实就是普通函数的优先级大于模板函数

2.类模板

template<class T1,class T2,...>
class 类模板名
{...
};

类模板必须显式实例化

类模板的声明和定义分离:

template<class T>
class 类模板名
{
public:f(T a){}
};
template<class T>//还要写
类模板名<T>::f(T a)
{...
}

普通的类

类名就是类型,

类模板:

类型=类模板名<模板参数>

指定类域要用类型

不过类的声明和定义不要轻易分离,分离到两个文件里面会报错

http://www.xdnf.cn/news/7423.html

相关文章:

  • 小土堆pytorch--神经网路的基本骨架(nn.Module的使用)卷积操作
  • 交叉引用、多个参考文献插入、跨文献插入word/wps中之【插入[1,3,4]、跨文献插入】
  • interface接口和defer场景分析
  • C++--内存管理
  • 动态规划-LCR 089.打家劫舍-力扣(LeetCode)
  • 国产化替代对金融行业有哪些影响?如何应对?
  • 创业与产品设计中的“三个一”法则
  • 基于正点原子阿波罗F429开发板的LWIP应用(1)——网络ping通
  • 前端测试策略:单元测试到 E2E 测试
  • ASIC和FPGA,到底应该选择哪个?
  • C# NX二次开发-求体、面的最小包容圆柱
  • 使用 nvm 管理 Node.js 和 npm 版本
  • Scala:size 和 length 的区别
  • 深入浅出IIC协议 -- 第二篇:FPGA数字接口设计方法论
  • IEEE Communications Magazine 2025年1-3月论文速览
  • 理解PostgreSQL查询执行计划(三)--复杂操作篇
  • TB开拓者策略交易信号闪烁根因及解决方法
  • flatMap():map + flat 的组合,简化 JavaScript 数组处理逻辑
  • ARMv7的NVIC中断优先级
  • MYSQL8.0常用窗口函数
  • Qt Widgets模块功能详细说明,基本控件:QCheckBox(三)
  • winrar 工具测试 下载 与安装
  • 计算机网络 第三章:运输层(一)
  • mcp 学习第二篇
  • Python在自动驾驶数据清洗中的应用
  • Java后端面试八股文大全(2025最新版)
  • 5月19日复盘-YOLOV4
  • 采用CDN技术时域名解析流程
  • Java-List集合类全面解析
  • DAY 30 模块和库的导入