首页 > 编程语言 >C++模板基础知识

C++模板基础知识

时间:2022-10-07 15:47:27浏览次数:53  
标签:int T2 C++ 基础知识 v0 v1 Test 模板

源码编译环境:win10 x86

反汇编软件:IDA Pro(胖大妈)

第一次接触到模板是在C#的泛型编程,对其表面的理解是可以对一些约束范围内参数类型的方法进行重用,可以少写一些方法。在后面接触C++和汇编后开始疑惑,模板的原理?开始疑惑为什么模板的声明和实现分离后会导致不能正常链接的问题?模板的匹配机制是什么?在学习和研究中对测试代码进行反汇编查看其原理,然后把这些做一下笔记。模板编译原理暂时还不知道,后面找时间看看编译原理,在回来补充相关的笔记。

模板分函数模板和类模板,将函数或方法内部的参数和内部数据类型提取出来作为模板的参数,然后编译器为具体类型生成针对这个类型的方法体或者函数。

模板推荐写在同一文件里,一般会放在hpp文件里。

模板声明实现分离

明确生成模板实例:

//mb.h
template<typename T>
T Add(T v1, T v2);
//mb.cpp
#include "mb.h"
template<typename T>
 T Add(T v1, T v2)
{
	return v1+v2;
}
 template int Add(int v1, int v2);//明确生成模板实例
//测试代码
int result= Add<int>(1, 2);
std::cout << result << std::endl;

 如果在没有添加明确生成模板,代码将不能编译编译通过。

外名模板

//TODO  我自己电脑没编译通过  待补

模板参数自动推导

模板有自动推导功能,当模板自动推导出参数类型时,就可以不在模板实参列表中写明,这个时候模板可以像正常的方法或函数一样使用。

模板参数推导条件:

1.编译器只根据调用时给的实参列表来推导

2.与函数返回值无关

3.可推导参数必须位于参数列表末尾

T2 Test(T1 v1, T3 v3) {
	T0 v0;
	T2 v2 = T2(0);
	return v2 - v1 - v3;
}
int main()
{
	//第一个<double T2
	//第二个int T0
	//第三个double T1
	//T3 自动推导
	//tenp=-3.0d
	double temp= Test<double,int,double>(0.1f, 2.0f);
}

结论:返回值T2是必须要给定类型的,T0虽然没有用到,但是模板里有,且是模板的第一个参数,T1不知道为啥不能自动推导。

证明T0必须指定类型过程:

当指定返回值类型,方法的参数列表自动推导的情况下,依然不能忽略T0参数类型。

template<typename T0,typename T1,typename T2=double,typename T3>
T2 Test(T1 v1, T3 v3) {
//同上
//T0 int,T1 float,T2 double,T3 float
}
int main()
{
	double temp= Test<int>(0.1f, 2.0f);
}

反编译分析

template<typename T0,typename T1,typename T2=double,typename T3>
T2 Test(T1 v1, T3 v3) {
	T0 v0;
	T2 v2 = T2(0);
	return v2 - v1 - v3;
}
int main()
{
	double t1= Test<int>(0.1f, 2.0f);
	double t2 = Test<int>(1, 2);
}

这是编译的源码,用两个float和两个int的模板进行对比。

这是反编译的源码,j_??$Test@HMNM@@YANMM@Z/j_??$Test@HHNH@@YANHH@Z这是方法名,模板的方法名,大概率也是和函数重载一样使用名字倾轧技术(name mangling)。

模板静态变量

普通函数中的静态变量可以解释为函数自有,不同函数之间的同名静态变量不通用,如果是模板的静态变量会怎么处理呢。

template<typename T0,typename T1,typename T2=double,typename T3>
T2 Test(T1 v1, T3 v3) {
	static T0 v0=T0(0);
	std::cout << "v0初始值:" << v0 << std::endl;
	v0 += v1;
	std::cout << "v0结果值:" << v0 << std::endl;
	T2 v2 = T2(0);
	return v2 - v1 - v3;
}
int main()
{
	double t1= Test<int>(2.0f, 2.0f);
	double t2 = Test<int>(3.0f, 4.0f);
	double t3 = Test<int>(1, 2);
	double t4 = Test<int>(3, 4);

}

我们修改一下上面的方法,在方法里声明一个静态变量,并且让这个静态变量与第一个参数进行加等于操作。

v0初始值:0
v0结果值:2
v0初始值:2
v0结果值:5
v0初始值:0
v0结果值:1
v0初始值:1
v0结果值:4

从中我们可以知道,前面两个模板共用了一个静态变量,后两个模板共用了一个静态变量。

反汇编分析:

从中我们可以发现,flaot模板调用的同一个方法(int同),那就和普通方法的处理规则一样了。

所以,我们写的模板方法,其本质就是编译器给我们生成了一个普通方法。

标签:int,T2,C++,基础知识,v0,v1,Test,模板
From: https://www.cnblogs.com/zjr0/p/16759173.html

相关文章

  • 【模板】筛法
    \(prime\)constintN=1e7+10;intprime[N];boolnotprime[N];intminprime[N];voidprime_sieve(constintmaxn){ registerinti,multi_helper; registerin......
  • C#的基础知识
    大家好,欢迎大家跟我学c#的基础知识,不同的书籍学习内容都不一样,但是我总结了一个c#的基础知识,想巩固的请看下,有想学或者想复习的朋友可以找我一起学,有什么不会的也可以问我,......
  • C++11特性(上)
    写在前面今天我们谈谈C++的一些语法,这些语法是C++11标准下新增的.有的人感觉学C++很难,那么C++11标准出来之后你会发现学习的成本又增加了.C++11增添了很多特性,有有用的,......
  • C++绘制玫瑰花
    C++绘制玫瑰花源码#include<stdio.h>#include<windows.h>#include<math.h>#include<graphics.h>#include<mmsystem.h>#pragmacomment(lib,"winmm.lib")//定......
  • C/C++基于朋友圈的商品推荐系统
    C/C++基于朋友圈的商品推荐系统基于朋友圈的商品推荐【课题内容和要求】模拟基于朋友圈的商品推荐,可以用于任何电商,如淘宝、京东等。假设目前用户有100人,每人均有自己......
  • 微信小程序排行榜页面模板
    1需求在开发一款背单词的微信小程序时,为了加强用户的体验感,刺激用户积极学习,小程序中需要有排行榜的模块。通过打开天数来排名,让用户有攀比学习的心里。具体的页面截图如......
  • 模板基类与正确的派生类函数调用--Effective C++ Item 43
    问题描述假设我们有这样一个业务场景,我们管理着许多公司,每个公司都有一个自己的许多日志信息需要处理,于是为了方便,我们写了一个模板类用来处理这些公司的信息,并且将这些公......
  • MySql基础知识总结
    Mysql基础知识总结一、Mysql的安装与卸载(Windows环境)二、Mysql的连接方式三、Mysql的基本常用语句四、Java连接Mysql技术Java连接Mysql的步骤在Java项目中写......
  • C/C++语言 MD5例子
    之前研究了一下在C中进行MD5加密,由于找了很久没有找到现成的库文件,所以所幸自己去写了一下。个人感觉C的便捷性没有Python好的原因就是这里。下面是我写的一个例子。mian......
  • 设计模式系列1 - 模板模式&策略模式
    分别讲述模板模式和策略模式的使用姿势,以及两者的区别,基于java。往期精选(欢迎转发~~)Java全套学习资料(14W字),耗时半年整理消息队列:从选型到原理,一文带你全部掌握肝了......