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

现代 C++ 模板教程 学习笔记

现代C++模板教程

看了这个教程,自己记录一些内容,不一定靠谱。

为什么需要模板?简单来说就是为了少写点重复的代码,让编译器自动帮我们生成。为了少写点函数,就有了函数模板,为了少写点类,就有了类模板。有时模板可能不适用于一些特殊的情况,就需要对模板进行 特化。有时我们还想限制模板参数的范围,就需要对模板参数进行约束

函数模板

初始函数模板

首先我们思考一个问题,函数模板是函数吗?
⭐️函数模板其实不是函数,只有对函数模板进行实例化,它才是一个函数

这是一个简单的函数模板,返回两个对象中较大的那一个

#include <iostream>template<typename T>	// 模板形参列表
T max(T a, T b) {return a > b ? a : b;
}struct Test {int v_{};Test() = default;Test(int v) : v_(v) {}bool operator>(const Test& t) const {return this->v_ > t.v_;}
};int main() {int a = 1, b = 1;std::cout << "max(a, b): " << ::max(a, b) << std::endl;Test ta(10), tb(20);std::cout << "max(ta, tb): " << ::max(ta, tb).v_ << std::endl;
}

compile explorer 看一下,可以看到编译器在编译期对函数模板进行了实例化,生成的函数为 int max<int>(int, int)Test max<Test>(Test, Test)
在这里插入图片描述

<模板参数>推导

使用函数模板时,编译器可以由传入的参数自动推导模板参数。例如max(a, b),传递了两个int类型参数ab,我们没有显式指定模板参数,编译器自动推导得到模板参数 T 为 int

但也不是什么情况下都可以进行自动类型推导的,例如 ab 两个类型不同,这时需要我们显式指定模板参数,例如 max<int>(a, b)

int a = 1;
double b = 2.3;
// std::cout << "max(a, b): " << ::max(a, b) << std::endl; // 无法进行自动类型推导
std::cout << "max(a, b): " << ::max<int>(a, b) << std::endl;	// 2
std::cout << "max(a, b): " << ::max<double>(a, b) << std::endl;	// 2.3

引用折叠/万能引用/完美转发

所谓模板参数推导,这里推导的模板参数是一个类型,例如 int 或者自定义的类型,在C++中谈到类型那就无法避开左值引用右值引用

对于右值引用 &&以及 std::move() 我的理解:右值引用 int&& 最常用于需要处理临时对象或大对象的场景,例如转移一块动态内存的所有权,std::move 是将类型转换为右值引用,但实际上这个 所有权的转移 不是 std::move 来做的,而是由移动构造函数移动赋值函数来做的, std::move 只是将变量转换成右值引用,而这个所谓的 && 符号也只是为了能匹配到 移动构造/赋值函数,一个简单的移动构造函数如下,它转移了动态内存块的所有权:

Buffer(Buffer&& other) noexcept : data(other.data), size(other.size) { // 转移资源other.data = nullptr; other.size = 0;
}

这里提一下 int&& ,这是一个右值引用,字面值常量是右值,那将 int&& 绑定到一个字面值常量的本质是啥?我们直接看编译器生成的汇编代码,可以发现以下这两段代码完全等价
分析:b 是一个右值引用,引用的是字面量 10,编译器会接把 10 这个常量值放到栈空间中,并将 b 绑定到这个地址

int && b = 10;
int a = 10;
int &b = a;

在这里插入图片描述在这里插入图片描述

有默认实参的模板类型形参


http://www.mrgr.cn/news/47859.html

相关文章:

  • 前缀和算法——优选算法
  • 大疆电机M3508 PWM控制
  • 谐波电压和电流哪个对电容器的伤害更大
  • busybox设置默认环境变量
  • 黑龙江APP等保测评:构建安全防线,守护用户数据
  • PyCharm下载安装汉化教程!pycharm激活
  • AI如何赋能数字化转型?
  • 互联网协议(IP)中最常用的端口
  • 基于RK3588+AI的深度学习功能PLC设计,支持Codesys
  • k8s中pod管理
  • 最新eclipse安装教程及安装包获取-附JDK安装
  • 力扣10.11
  • 谈到数据集成和数据分析,这三个概念你得分清楚!
  • Linux入门:进程状态与优先级
  • 线性自抗扰控制(LADRC)系统算法框图
  • Jetpack Compose 页面跳转 - 导航Navigation使用和封装
  • 如何在组织内推广和应用六西格玛设计?
  • 双十一买什么东西好?五大双11好物推荐分享!
  • LangChain 学习(三)
  • 【python】函数的返回值