news 2026/6/9 22:22:31

【Effective Modern C++】第一章 类型推导:1.理解模板类型推导

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Effective Modern C++】第一章 类型推导:1.理解模板类型推导

函数模板形如:

template<typename T> void f(ParamType param);

一次调用形如:

f(expr); //以某表达式调用 f

在编译期,编译器会通过expr推导T的类型和ParamType的类型(通常会包含一些修饰,例如const或引用符号等限定)。

T的类型推导结果分以下三种情况讨论:

1.ParamType具有指针或引用型别,但不是万能引用

类型推导规则如下:

  1. expr具有引用类型,先将引用部分忽略。
  2. 然后,对expr的类型和ParamType的类型执行模式匹配,来决定T的类型。
举例

模式声明如下:

template<typename T> void f(T& param); // param 是个引用

声明下列变量:

int x = 27; // x 的类型是 int const int xx= x; // cx 的类型是 const int const int& rx = x; // rx 是 x 的类型为 const int 的引用

各次调用的推导结果如下:

f(x); // T 的类型是 int,param 的类型是 int& f(cx); // T 的类型是 const int,param 的类型是 const int& f(rx); // T 的类型是 const int,param 的类型是 const int&

右值和指针方式同理:

template<typename T> void f(T* param); // param 是个指针 int x = 27; const int *px = &x; // px 是指向 x 的指针,类型为 const int f(&x); // T 的类型是 int, param 的类型是 int* f(px); // T 的类型是 const int, param 的类型是 const int*

2.ParamType是万能引用

类型推导规则如下:

  1. 如果expr是个左值,TParamType都会被推导为左值引用。
  2. 如果expr是个右值,则应用“常规"(即情况 1 中的)规则。
举例
template<typename T> void f(T&& param); // param 是个万能引用 int x = 27; const int cx= x; const int& rx = x; f(x); // x 是个左值,所以 T 的类型是 int&, param 的类型也是 int& f(cx); // cx 是个左值,所以 T 的类型是 const int&, param 的类型也是 const int& f(rx); // rx 是个左值,所以 T 的类型是 const int&, param 的类型也是 const int& f(27); // 27 是个右值,所以 T 的类型是 int, param 的类型就成了 int&&

3.ParamType既非指针也非引用

即按值传递,无论传入的是什么,param都会是它的副本,是一个新对象:

  1. expr具有引用类型,则忽略其引用部分。
  2. 忽略expr的引用性之后,若expr是个const对象,也忽略。若其是个volatile对象,同样忽略。
举例
template<typename T> void f(T param); //param现在是按值传递 int x = 27; //同前 const int cx = x; //同前 const int& rx = x; //同前 f(x); // T和param的类型都是int f(cx); // T和param的类型都是int f(rx); // T和param的类型都是int

即使cxrx代表const值,param仍然不具有const的类型。param是个完全独立于cxrx的一个副本。从而cxrx不可修改并不能说明param是否可以修改。

数组实参

一种边缘情况,数组类型有别于指针类型,但是在多数语境下,数组会退化成首元素的指针。

C++ 中没有真正的“数组形参”,因为函数无法直接接收数组;当数组传递给按值形参的模板时,编译器会把形参里的数组声明直接当作指针处理。但是:

尽管函数无法声明真正的数组类型的形参,但是它们能够将形参声明为数组的引用。在这种情况下T的类型会被推导成实际的数组类型。这个类型中会包含数组尺寸。

利用声明数组引用能力,可以创造出一个模板用来推导数组中含有的元素个数:

// 以编译期常量形式返回数组尺寸 // (该数组形参未起名字,因为我们只关心共含有的元素个数) template<typename T, std::size_t N> constexpr std::size_t arraySize(T (&)[N]) noexcept { return N; }

将函数声明为constexpr,能够使得其返回值在编译期就可以使用。从而在声明一个数组时,指定其尺寸和另一数组相同,而后者的尺寸则从花括号初始化形式计算得出:

int keyVals[] = { 1, 3, 7, 9, 11, 22, 35 }; // keyVals 含有 7 个元素 int mappedVals [arraySize(keyVals)]; // mappedVals 被指定与之相同

函数实参

函数类型也同样会退化成函数指针,并且针对数组类型推导的一切都适用于函数及其向函数指针的退化。如下:

void someFunc(int, double); // someFunc 是个函数,其类型为 void(int, double) template<typename T> void f1(T param); // 在 f1 中,param 按值传递 template<typename T> void f2 (T& param); // 在 f2 中,param 按引用传递 f1(someFunc); // param 披推导为函数指针,具体类型是 void (*)(int, double) f2(someFunc); // param 披推导为函数引用,具体类型是 void (&)(int, double)

总结

  • 在模板类型推导时,有引用的实参会被视为无引用,它们的引用会被忽略
  • 对于通用引用的推导,左值实参会被特殊对待
  • 对于传值类型推导,const/volatile实参会被认为是non-const的和non-volatile
  • 在模板类型推导时,数组名或者函数名实参会退化为指针,除非它们被用于初始化引用

原著在线阅读地址

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 11:18:25

智能SQL生成革命:如何让AI帮你写代码,数据分析效率提升300%

智能SQL生成革命&#xff1a;如何让AI帮你写代码&#xff0c;数据分析效率提升300% 【免费下载链接】sqlcoder-7b-2 项目地址: https://ai.gitcode.com/hf_mirrors/defog/sqlcoder-7b-2 还在为写SQL发愁吗&#xff1f;想象一下&#xff0c;你只需要用自然语言描述需求&…

作者头像 李华
网站建设 2026/6/7 11:54:26

AI超清增强技术入门必看:EDSR网络结构与原理简析

AI超清增强技术入门必看&#xff1a;EDSR网络结构与原理简析 1. 技术背景与问题定义 图像超分辨率&#xff08;Super-Resolution, SR&#xff09;是计算机视觉领域的重要任务之一&#xff0c;其目标是从一张低分辨率&#xff08;Low-Resolution, LR&#xff09;图像中恢复出高…

作者头像 李华
网站建设 2026/6/8 19:19:38

Llama3-8B训练数据解析:为何英语表现更强?技术拆解

Llama3-8B训练数据解析&#xff1a;为何英语表现更强&#xff1f;技术拆解 1. 引言&#xff1a;Llama 3 的定位与核心价值 Meta-Llama-3-8B-Instruct 是 Meta 于 2024 年 4 月发布的中等规模指令微调语言模型&#xff0c;作为 Llama 3 系列的重要成员&#xff0c;其在性能、效…

作者头像 李华
网站建设 2026/6/8 15:22:48

剪贴板粘贴就能抠图?CV-UNet镜像便捷操作揭秘

剪贴板粘贴就能抠图&#xff1f;CV-UNet镜像便捷操作揭秘 1. 技术背景与使用场景分析 图像抠图&#xff08;Image Matting&#xff09;作为计算机视觉中的细粒度分割任务&#xff0c;长期以来在设计、电商、影视后期等领域具有广泛需求。传统方法依赖人工绘制Trimap或复杂选区…

作者头像 李华
网站建设 2026/6/9 20:07:52

老旧证件照修复新方法,GPEN镜像轻松搞定

老旧证件照修复新方法&#xff0c;GPEN镜像轻松搞定 你是否曾翻出泛黄模糊的老旧证件照&#xff0c;面对褪色、划痕和低分辨率的问题束手无策&#xff1f;传统图像处理手段往往只能“修修补补”&#xff0c;难以真正还原人物神态与细节质感。如今&#xff0c;借助深度学习驱动…

作者头像 李华
网站建设 2026/6/8 14:51:28

Hunyuan-MT-7B显存优化:INT8量化部署性能实测

Hunyuan-MT-7B显存优化&#xff1a;INT8量化部署性能实测 1. 背景与技术挑战 随着多语言翻译模型在跨语言交流、内容本地化和全球化服务中的广泛应用&#xff0c;对高效、低成本部署大模型的需求日益迫切。Hunyuan-MT-7B作为腾讯混元开源的最强翻译模型之一&#xff0c;支持包…

作者头像 李华