模板类型推导 T

C++模板实参类型推导 1. 什么是模板 C++特性之一,批量生成代码的手段。 2. 模板有什么应用? 1. 泛型编程 例如:std::vector 2. 模板元编程 利用模板的特化等特性,在编译期计算出结果。 例如: 3.模板实参类型推导 虽然模板这么牛逼,但是今天我们不讲上述两个特性,我们讲一下细节:给模板填入一个类型时,模板是如何推导出实参(T)的类型。 1.实参确定的几种方式 编译期间,编译器一定会确定每个模板实参T的类型,一般开发者指定类型有以下几种方式。 显式指定,如图 fun(15); 直接指定T的类型为int, 阅读详情
  1. 类型推导

    • c++98

      • 只有template一种.
    • c++11

      • auto template并做了一点改良.
    • c++14

      • 在c++11的基础上做了加强auto和decltype的组合.
    • 推导优劣

      • 好处

        • 少打代码.
        • 可以声明不确定类型的变量类型.
        • 必须初始化.
        • 在修改某返回类型时,不用改太多.
      • 劣势

        • 阅读性不强.
        • 甚至可能得不到预期的.
    • 地位

      • C++的新特性基本都是基于类型推导,所以需要好好的学习掌握类型推导的原理.
    • 主要内容

      • 类型推导如何实现的,怎么看类型推导出来的结果.
    • 核心

      • 都是编译器需要支持对应语法.
  2. 类型推导

    • 关系

      • template支持类型推导。
      • auto使用了template的规则进行类型推导,也有部分的差异。
      • decltype则是全新的逻辑.
    • 总纲

      • 变量本身强相关. &,*都是.
      • 变量本身不想管. 值传递.
    • 原则

      类型规则说明
      T&T = valuetype - argtypeargtype中包含&
      T*T = valuetype - argtypeargtype中包含*
      T&&T = valuetype - argtypeargtype中包含&&
      T非指针T = valuetype - argtypeargtype最终的变量是*类型.
  3. T&

    • 说明

      • argtype中包含&,即左值右值和const,volatile,*,none之类的修饰进行分析.
      • 这里仅仅部分的案例.
    • 分析

      • 引用就是指针,指针则会关注指针指向的类型.
      • 即对于指针指向内容的约束,只能扩大,不能缩小.
    • 概括

      • 引用取对象的完整类型.
      • T = valuetype - argtype
    • 案例一分析

      template<typename T>
      void show(const T& a) {
         // error code
         a.nice();
      }
      int main() {
         show(1);
      }
      
      • T = valuetype - argtype = int&& - const &,利用集合运算. 则T = int.
      • 最终的argtype = const int&
      • 因为有const所以&&等价于&.
    • 案例二分析

      template<typename T>
      void show(const T& a) {
         // error code
         a.nice();
      }
      int main() {
         int a = 1;
         show(a);
      }
      
      • T = valuetype - argtype = int & - const & = int.则T = int.
      • 最终的是valuetype = const int &
    • 案例三分析

      template<typename T>
      void show(T& a) {
         // error code
         a.nice();
      }
      int main() {
         int a = 1;
         show(a);
      }
      
      • T = valuetype - argtype = int & - & = int,则T = int.
      • 最终的valuetype = int &.
    • 案例三分析

      template<typename T>
      void show(T& a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(a);
      }
      
      • T = valutype - argtype = const int & - & = const int, 则T = const int
      • 最终 valuetype = const int &
    • 案例四

      template<typename T>
      void show(T&& a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(&a);
      }
      
      • 这里加入了指针类型,因为指针类型和变量类型是两个独立的存在。
      • T = valuetype - argtype = const int * && - && = const int *.
    • 总结

      • 引用,不论是&,&&都可以按照这个表达式进行计算. 但是需要区分右值&&和万能引用的场景.
      • T&&是万能,其他格式都是右值引用.
  4. T*

    • 说明

      • argtype中的值传递是指针类型。
    • 指针类型和指向类型

      • 指针类型: 是指针这个变量本身的类型.有对应的修饰。
      • 指向类型: 是地址对应的变量是某个类型.
    • 概括

      • 指针取指向类型,而不是变量本身.
      • T = valtype - argtype.
      • 注意: 变量的引用和指向类型可能会有歧义.
    • 案例分析

      • 比较好理解的就是typedef int *int_ptr;
      • 即*int_ptr = int.
      • 同理typedef const int *c_intptr;,*c_intptr = const int.
      • 变量本身的所有的类型修饰一般在对应*之后.
      • typedef的可阅读性变差,C++11之后就变成使用using了.
    • 核心

      • T&实际就是*类型.
    • 案例一

      template<typename T>
      void show(T* a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(&a);
      }
      
      • &a是const int * &&类型.但是argtype中没有引用所以忽略&&.
      • 则T = valtype - argtype = const int* - * = const int
    • 案例二

      template<typename T>
      void show(T* &a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(&a);
      }
      
      • 编译错误,因为&a是右值,对变量本身有限制。
      • 将T*&a改成T*&&a即可.
    • 案例三

      template<typename T>
      void show(const T* a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(&a);
      }
      
      • &a是const int * &&类型.但是argtype中没有引用所以忽略&&.
      • 则T = valtype - argtype = const int* - const* = int.
  5. T&&

    • 说明

      • 万能引用,可以匹配任意类型.
    • 核心

      • 唯一可以推导出T是引用类型的机制.前面的T都是基本类型。
      • 即T =里面不存在&类型.
      • 比如上面的都是int,const int之类,没有&,万能引用可以.
    • 简要

      • 右值引用仅仅用来匹配右值,太大材小用了,毕竟右值的描述性字段很少,就基础的。
      • 用来扩展功能挺好的。
    • 概括

      • 万能引用形式像右值引用,但是也有右值匹配的功能.
      • T = valuetype - argtype.,注意,这里的& - && = &
    • 注意

      • 因为右值一般是消亡值,所以可以回收利用资源.
    • 案例一

      template<typename T>
      void show(T&& a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(&a);
      }
      
      • &a是const int *&&.
      • T = valuetype - argtype = const int *&& - && = const int *.
    • 案例二

      template<typename T>
      void show(T&& a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(a);
      }
      
      • a是一个const int &类型。
      • T = valuetype - argtype = const int & - && = const int &.
    • 案例三

      template<typename T>
      void show(T&& a) {
         // error code
         a.nice();
      }
      int main() {
         show(7);
      }
      
      • 7是int &&类型.即普通右值.最终有int&&.
      • T = valuetype - argtype = int && - && = int.
  6. T

    • 说明

      • 就是一个值传递,形参.
    • 核心

      • 形参就是和原本的参数无关,拷贝值,可以随意操作.
    • 概要

      • 值传递,valuetype仅仅保留基础类型.
      • 不将const,volatile之类的修饰用于推测.
      • T = valuetype - valuetype - const volatile XXX
    • 案例一

      template<typename T>
      void show(T a) {
         // error code
         a.nice();
      }
      int main() {
         show(7);
      }
      
      • T = valuetype - argtype = int.
    • 案例二

      template<typename T>
      void show(T a) {
         // error code
         a.nice();
      }
      int main() {
         const int a = 1;
         show(a);
      }
      
      • T = valuetype - argtype = int.
      • 去掉了const之列的.
    • 案例三

      template<typename T>
      void show(T a) {
         // error code
         a.nice();
      }
      int main() {
         const int *a = nullptr;
         show(a);
      }
      
      • a是指针,指向的类型是const int *.
      • T = argtype - valuetype = const int *
      • 本身无任何修饰.
    • 案例四

      template<typename T>
      void show(const T a) {
         // error code
         a.nice();
      }
      int main() {
         const int *a = nullptr;
         show(a);
      }
      
      • 同案例三.只是对入参加了修饰.
    • 案例五

      template<typename T>
      void show(T a) {
         // error code
         a.nice();
      }
      int main() {
         const int *const a = nullptr;
         show(a);
      }
      
      • 同上,这里加了a变量的类型修饰.
    • 案例六

      template<typename T>
      void show(T& a) {
         // error code
         a.nice();
      }
      int main() {
         const int *const a = nullptr;
         show(a);
      }
      
      • a是const int *const类型.const int *是指向的类型,后面的是const类型是自身的类型.
      • 因为这里加了T&.
      • T = valuetype - argtype = const int * const& - & = const int * const.
    • 案例七

      template<typename T>
      void show(T& a) {
         // error code
         a.nice();
      }
      int main() {
         const int *volatile a = nullptr;
         show(a);
      }
      
      • 和上面略有差异.
      • a指向类型还是const int *,但是本身是一个volatile修饰的.
      • 所以T = valutype - argtype = const int * volatile & - & = const int * volatile.
  7. 总结

    • 引用,完整类型,减法.

    • 指针,完整类型,减法.

    • 右值,完整类型,减法.

    • 万能,完整类型,减法.

    • 形参,普通类型,多减.

用示波器抓一次MIPI D-PHY的波形,手把手教你读懂HS模式和LP模式的切换时序 本文详细解析了MIPI D-PHY信号的双模切换机制,包括高速模式(HS)和低功耗模式(LP)的波形捕获与诊断技巧。通过示波器设置、关键状态分析和实战案例,帮助工程师快速定位信号完整性问题,提升调试效率。 阅读详情

相关推荐

virtualbox虚拟机里面最顶部没有控制、设置和帮助等选项

无意中操作,导致virtualbox虚拟机里面最顶部没有控制,设置和帮助选项  virtualbox虚拟机窗口显示如下如: 如何设置,窗口显示如下图所示呢: virtualbox虚拟机窗口模式显示设置,切换可以通过如下图所示操作进行切换: PS:一定要是右边的Ctrl+C

WEL测试 8780

c++11模板:获取函数的参数类型

假设我们已经知道一个函数类型的定义double(unsigned char*, unsigned char*),如何获取这个函数定义中的输入和输出参数类型呢? c++11提供的模板函数std::function和std::tuple_element可以将一个函数定义的输入和输出参数类型一个一个解析出来,下面是实现代码 #include &lt;functional&gt; #include &lt...

10km的专栏 8179

第1.1节 构网型 vs. 跟网型:根本区别与技术原理

构网型与跟网型变流器的本质区别在于控制哲学与等效模型。跟网型变流器采用"电压跟随,电流注入"策略,等效为受控电流源,依赖电网电压作为参考,在弱电网下存在稳定性问题。构网型变流器采用"自主同步,电压构建"策略,等效为受控电压源,能主动构建电压和频率,具备自主运行、黑启动和电网支撑能力。两者的核心差异体现在同步机制、电网依赖性、故障行为和系统支撑等方面。构网型变流器更适合高比例新能源、弱电网和微电网场景,是未来电力系统的重要发展方向。

技术工作者 1395

C++ 推导模板 template <typename T> , T的类型,std::vector<int>,推导出 int 类型。

【代码】C++ 推导模板 template , T的类型,std::vector,推导出 int 类型。

liulilittle的博客 428

最小二乘法(看完即会)

其中,X是数据矩阵,每一行是一个数据点,每一列是一个自变量(包括截距项),Y是观测值向量,β是待求的系数向量。为了找到使S最小的a和b的值,我们需要对S求关于a和b的偏导数,并令它们等于零。最小二乘法的数学公式通常用于线性回归问题,其中目标是找到一条直线(或更高维度的超平面),使得这条直线与给定数据点的误差平方和最小。同样地,通过求偏导数和令偏导数等于零,我们可以得到一个线性方程组,解这个方程组可以找到最优的b_0, b_1, …+ b_m*x_m,其中b_0是截距,b_1到b_m是各个自变量的系数。

qlkaicx的博客 2万+

Ubuntu 22.04蓝牙开关秒关?别慌,可能是这个Intel固件文件在搞鬼

本文深入解析Ubuntu 22.04蓝牙开关秒关问题,指出Intel固件文件缺失是常见原因,并提供详细修复方案。通过确认硬件型号、检查固件文件及智能替代方案,帮助用户快速解决蓝牙故障,提升系统稳定性。

weixin_30247307的博客 755

C++11获取变量类型

class TestA { }; int main() { TestA a; std::cout << typeid(a).name() << std::endl; }

qq_23350817的博客 1482

Jetson Orin NX深度学习环境配置全攻略:从JetPack到PyTorch避坑指南

本文提供Jetson Orin NX深度学习环境配置的完整避坑指南。重点讲解如何正确利用JetPack SDK作为系统基石,使用Miniforge管理Python环境,并安装与CUDA版本严格匹配的PyTorch特供版本。通过详细的步骤和验证方法,帮助开发者在ARM架构的嵌入式平台上高效搭建稳定的AI开发工作站。

yolo5detector的博客 272

C++11新增特性:定义未知类型的变量之auto关键字

c++11新增特性:auto关键字声明未知类型的变量

小熊全栈 1785

制作你自己的yolov5数据集并进行训练

项目地址:make-your-yolov5_dataset 一、数据集标注软件 labelImg labelMe 精灵标注助手 更多的标注工具你可以去看:深度学习图像标注工具汇总 、 十个最常用深度学习图像/视频数据标注工具 、 百度一下 在这里我选择使用labelImg 二、数据集标注 下载labelImg 解压,直接打开labelimg.exe labelImg标注数据 标注完成后即可获得VOC格式(生成.xml文件)的数据 目录结构: dataset │ ├─Annotations .

年少的勇气已经用完,剩下的就是三思而后行 1万+

ADAS方案设计-CAN网络管理与休眠唤醒机制

文章摘要:本文介绍了车载控制系统的五种工作模式及其转换条件,包括睡眠模式、准备睡眠模式、就绪睡眠模式、正常工作模式和重复消息状态。系统唤醒条件包括接收到网络管理报文或电源ON档信号,休眠条件则需满足电源OFF档、功能完成等多重要求。针对下挂节点的网络管理报文发送规则,详细说明了不同状态下的报文发送策略,特别是在哨兵模式、OTA模式等特殊场景下的处理方式。系统在满足休眠条件后会立即停止发送下挂节点网络管理报文,确保电源管理的有效性。

xiandang8023的博客 325

C++模板类型推导全解析:从T推导到auto与完美转发

从C++模板编程的基础概念出发,深入剖析函数模板中模板参数T的推导机制,涵盖按值传递、引用形参、万能引用等常见场景。通过对比auto与模板推导的异同,解释initializer_list处理差异,并介绍decltype(auto)在精确类型推导中的应用。结合数组退化、字符串字面量、非推导上下文等易错细节,展示完美转发中std::forward的工作原理,帮助开发者快速定位编译错误,提升泛型编程能力。

weixin_26899659的博客 214

ONVIF协议简介与协议测试工具使用详解

Onvif协议及协议测试工具使用详解

dvlinker的技术专栏 3万+

Modern Effective C++:item 1 理解模板类型推导

当 T 是一个模板参数类型,并且T是推导出来的类型,T&&才是通用引用。T 是模板参数,ParamType 是函数参数的实际类型,它可能是 T 本身,也可能是对 T 进行了一些修饰后的类型(如 const T&、T* 等)。数组与指针形参这样的等价是C语言的产物,C++又是建立在C语言的基础上,它让人产生了一种数组和指针是等价的的错觉。ParamType 是函数参数的类型,它可以是 T 本身,也可以是对 T 进行了一些修饰后的类型,比如加上 const、&(引用)、*(指针)等。依赖于模板类型推导。

_ 1581

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【C++】详解模板类型推导

从这样的角度来看,C++的模板类型推导毫无疑问取得了巨大的成功:成百上千的程序员都在向函数模板传递实参,并拿到了完全满意的结果,而其中鲜有人能够将类型推导的过程阐述出来。依照按值传递形参的类型推导规则,此时ptr的const性会被忽略,param被推导成const char*,即一个指向可以改变的,指向一个const字符串的指针(或者说顶层const在值传递的过程中被消除),在推导过程中,ptr指向对象的常量性会被保留,但自身的常量性被忽略。在这种情况下,T的类型会被推导成实际的数组类型!

Friday 1168

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C++理解模板类型推导

通过引用参数的类型声明是T&&,如果expr是一个左值,T和ParamType都会被推到成左值引用(T&&->T&);如果expr是const的,也要忽略掉const.如果是volatile的,也要忽略掉。如果expr的类型是一个引用,忽略引用的部分,然后利用expr的类型和ParamType对比去判断T的类型。编译器在对T的类型进行推导时,不仅仅只取决于‘expr’的类型,还取决于‘ParamType’的形式。虽然通常情况下,一个数组会退化成一个指向其第一个元素的指针,但是数组类型的指针类型是不一样的。

m0_73952999的博客 446

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

条款1:理解模板类型推导

Effective Modern C++之条款1

weixin_43739503的博客 512

C++模板类型推导全解:从T到auto、decltype与引用折叠

在C++泛型编程中,类型推导是编译器从实参推断模板参数类型的核心机制,也是理解模板、auto 和现代 C++ 标准库的基石。按值传递会发生类型退化,数组退化为指针、顶层 const 被忽略;而引用形参和转发引用(T&&)则保留更多类型信息,并触发引用折叠规则,配合 std::forward 实现完美转发。decltype 与 auto 分别代表“保留全部类型细节”和“退化的简化推导”,二者结合的 decltype(auto) 常用于包装器返回类型。C++17 引入的类模板实参推导(CTAD)进一步简化了对象

weixin_33391446的博客 217

条款1:理解模版性别推导

依照按值传递形参的型别推导规则,ptr的常量性会被忽略,param的型别会被推导为const char *,即一个可修改的、指涉到一个const字符串的指针。在型别推导的过程中,ptr指涉到的对象的常量性会得到保留,但其自身的常量性则会以复制方式创建新指针param的过程中被忽略。在第二个以及第三个调用语句中,由于cx和rx的值都被指明为const,所以T的型别被推导为const int,从而形参的型别就成了const int&。这意味着,无论传入的是什么,param都会是它的一个副本,也即一个全新对象。

weixin_41554427的博客 1325

C++模板类型推导

模板类型推导 对于模板函数来书,编译器需要根据实际传入的参数来推导模板类型T。例如,假设我们有下面这个模板函数: tempalte<typename T> void f(T& param); // param si a reference 同时声明了这些变量: int x = 27; // x is an int const int cx = x; // cx is ...

jinzhu1911的专栏 1287

模板类型推导

被推导为了真正的数组,这个类型包括了数组的大小,在这个例子中T被推导为const char[13],f的形参(该数组的引用)的类型则为const char (&)[13]rx的类型是一个引用,T也会被推导为一个非引用 ,这是因为rx的引用性在类型推导中会被忽略。数组类型的形参会视作指针形参,所以传值给模板的一个数组类型会被推导为一个指针类型。T的类型推导不仅取决于传入函数的实参类型,也取决于Param的类型。虽然函数不能声明形参为真正的数组,但是可以接受指向数组的引用。的类型为ParamType,就是。

DDlsss的博客 489

C++ 模板类型推导机制详解

C++作为一门强大的编程语言,其模板机制极大地提升了代码的复用性和灵活性。而模板类型推导则是现代C++编程中的核心机制之一,它使得泛型编程更加简洁高效。理解类型推导的规则,不仅能帮助开发者编写更优雅的代码,还能避免潜在的编译错误。本文将深入探讨C++模板类型推导的核心机制,帮助读者掌握这一关键技术。在函数模板调用时,编译器会根据实参自动推导模板参数的类型。例如,对于`template。C++ 模板类型推导机制详解。模板参数推导的基本原理。

owcqrx_941的博客 251

《Effective Modern C++》条款1:模板类型推导

本章节主要针对于template的类型推到进行一个简介; 对于一下template模板: template<typename T> void fun(ParamType param); fun(expr); 以往自己认为T的类型是由expr来决定的,之后作用于ParamType,但是今天看了这张发现自己的理解有点问题; 事实情况是T的类型是什么取决于ParamType以及expr的具体形式,并不是孤立存在的; 因此,T的类型不仅取决于expr的类型,也取决于ParamType的类型; 本章

m0_66776925的博客 486

C++ 模板类型推导的底层实现

C++的模板类型推导是现代C++编程中不可或缺的核心机制,它使得泛型编程变得灵活而高效。从简单的函数模板到复杂的元编程,类型推导在编译期间自动推断模板参数,减少了冗余代码。其底层实现机制却鲜为人知。本文将揭开模板类型推导的神秘面纱,探讨其背后的原理与实现细节。当调用函数模板时,编译器会根据实参类型推导模板参数类型。例如,对于`template。C++模板类型推导的底层实现。

mkunsu_687的博客 203
上一篇: 查看类型推导结果
下一篇: 模板推导数组函数,获取数组长度
「已注销」
博客等级 码龄11年 210粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值