首页 > 编程语言 >C++模板真的没有教材讲的呢么简单

C++模板真的没有教材讲的呢么简单

时间:2024-11-08 20:47:46浏览次数:6  
标签:return int C++ 参数 template 教材 实参 模板

        模板和泛型编程息息相关,但是大多数人对模板的了解可能只是教材上的一个compare函数,但实际上模板的内容很丰富,学起来也比较抽象,我会结合我所了解的一部分模板内容进行解释。

        本文内容参考《C++ Primer》

目录

定义模板

模板实参推演

可变参数模板

模板特例化


定义模板

        定义模板需要用到template关键字来标识一个模板的开始

        语法:template<typename(class) T> 圆括号中的class和typename的作用是相同的,可以使用其中任意一个来定义模板,T为模板的类型名字,也可以定义多个模板名称,例如template<typename T,class U>,意为定义两个模板类型,一个为T,另一个为U

        在这行语句的下面我们就可以编写一个模板函数或者一个模板类,需要注意的是,每次定义模板的时候都需要重写这条语句

模板实参推演

        在我们调用模板函数的时候,编译器会根据函数中的实参来确定其中的模板参数,这种从函数实参来确定模板实参类型的过程叫做模板实参推演

template<typename T ,typename U>
bool compare(T a, U b) {
	return a > b;
}

int main() {
	cout << compare(1.2, 3.4) << endl;
	cout << compare(2, 1.3) << endl;
	//cout << compare(2, "hello") << endl;
    //整形和字符串类型无法比较
	return 0;
}

        如上述代码,两次函数调用,均通过实参的类型来确定模板的参数类型,需要注意的是,在使用两个模板的时候,函数内部对应的两个参数的操作必须兼容。 

        也可以指定返回值类型为模板,但是无法通过实参来去确定返回值的类型,所以需要显示的指定返回值类型

template<typename T1 ,typename T2>
T1 func(T2 a) {
	return a;
}

int main() {
	func<int>(2);
	return 0;
}

         显示模板的实参按照从左至右的顺序与对应的模板参数匹配,只有最右侧的可以省略,而且他必须可以从函数参数推导过来

template<typename T ,typename U>
U func(T a) {
	return a;
}

int main() {
	//func<int>(2);
	func<int, double>(3);//T对应int U对应double
	return 0;
}

可变参数模板

        一个可变参数模板就是一个接受可变参数数目的模板函数或模板类,可变数目的参数被称为参数包,存在两种包:模板参数包,表示零个或多个模板参数;函数参数包,表示零个或多个函数参数

        语法:template<typename T,typename...  Args>,第二个typename后面的三个点表示Args是一个包

template<typename T,typename... Args>
void foo(const T a, const Args ... rest) {
	return;
}

int main() {
	foo(1, 2, 3, 4, 5, 6);//包中有5个参数
	foo(2.0, 'a', 3.4, 'c');//包中有三个参数
	foo("nihao");//空包

	return 0;
}

         根据上面的代码编译器会实例化三个函数

  • foo(int, int, int, int, int, int)
  • foo(double, char, double, char)
  • foo(char*)

        可见T的类型又传入的实参进行推导,后面的类型

模板特例化

        编写一个模板时,不可能做到对每一种类型都能很好的适配,所以有些数据类型的操作,需要进行特殊处理,这时就有了模板的特例化版本,比如compare函数,如果传入的是两个字符指针,我们想要比较的是两个字符串的大小,而直接返回 return a>b;比较的则是两个指针地址的大小,不符合我们的需求,所以我们需要对char* 进行特例化

#include<iostream>
using namespace std;

template<typename T>
bool compare(const T a,const T b) {
	cout << "compare" << endl;
	return a > b;
}

template<>
bool compare(const char* a, const char* b) {
	cout << "compare<char*>" << endl;
	return strcmp(a,b);
}

int main() {
	cout << compare(2, 3) << endl;
	const char* p1 = "nihao";
	const char* p2 = "hello";
	cout << compare(p1, p2) << endl;


	return 0;
}

        上述代码在执行过程中,第一个compare用普通版本,第二个compare用特例化版本

        以上仅仅是对模板简单的一些使用,如有问题,欢迎大家批评指正。

标签:return,int,C++,参数,template,教材,实参,模板
From: https://blog.csdn.net/weixin_58234579/article/details/143630162

相关文章

  • 题解:P11266 【模板】完全体·堆
    也算是对pb_ds库中的优先队列各种操作的科普?一些碎碎念提醒:你可以不看这部分,这部分算是作者探索未知功能的过程平常写优先队列的时候一般用不到对值进行修改或者删除的操作,所以我在看这到题的时候在想怎么才能实现题目中的操作,因为我不知道有什么成员函数可以直接获取具体哪......
  • C++——求a!+b!+c!的值,用一个函数fac(n)求n!。a,b,c的值由主函数输入,最终得到的值在主
    没注释的源代码#include<iostream>usingnamespacestd;intfun(intn);intmain(){   inta,b,c,sum;   cout<<"pleaseinputa,b,c:";   cin>>a>>b>>c;   sum=fun(a)+fun(b)+fun(c);   cout<<"a!+b!+c!="......
  • C++——求一个3*3矩阵主对角线元素之和。
    没注释的源代码#include<iostream>usingnamespacestd;intmain(){   inta[3][3],sum=0;   cout<<"pleaseinputmartix:"<<endl;   for(inti=0;i<3;i++)   {       for(intj=0;j<3;j++)       {           cin......
  • C++——分别声明Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新
    要求:(1)在两个基类中都包含姓名年龄性别地址电话等数据成员。(2)在Teacher类中还包含数据成员tile职称),在Cadre类中还包含数据成员POst(职务)。在Teacher.Cadre类中还包含数据成员wages(工资)。(3)对两个基类中的姓名、年龄、性别、地址、电话等数据成员用相同的名字,在......
  • C++ 函数对象、函数指针与Lambda表达式
    C++函数对象、函数指针与Lambda表达式函数指针函数指针(FunctionPointer)是指向函数的指针变量。它可以存储函数的地址,并通过该指针变量来调用该函数。函数指针的声明使用指针符号,指向的类型为函数的返回类型和参数列表,如int(funcPtr)(int,int);。函数指针的值可以指向相同......
  • 08C++选择结构(2)——教学
    一、逻辑变量教学视频存储类似灯亮或灯灭、是男还是女等结果只有两种可能的数据时,可以使用逻辑型变量。逻辑型变量用关键字bool定义,所以又称为布尔变量,其值只有两个false(假)和true(真),false和true是逻辑常量,又称布尔常量。流程图如下:英汉小词典:bool:布尔false:假true:真二、逻......
  • C++ 可变参数模板递归展开
    #include<iostream>usingnamespacestd;template<typenameHead,typename...Tail>doubleMax(Headfirst,Tail...rest){doubleMaxnum=0;Maxnum=Max(rest...);if(Maxnum<first)Maxnum=first;returnMaxnum;}......
  • 【QT项目】QT6项目之基于C++的通讯录管理系统(联系人/学生管理系统)
    目录一.项目背景二.创建工程工程创建添加文件 联系人类 功能类三.功能实现联系人类person.cppperson.h 查查询按钮槽函数返回按钮槽函数findperson.cpp:增addperson.cpp:删deleteperson.cpp:改changeperson.cpp:!!显示!!displayperson.cpp:清除clearp......
  • C++ 模板实参推断和引用折叠
    两个例外规则假定i是一个int对象,我们可能认为像£3(i)这样的调用是不合法的。毕竟,i是一个左值,而通常我们不能将一个右值引用绑定到一个左值上。但是,C++语言在正常绑定规则之外定义了两个例外规则,允许这种绑定。这两个例外规则是move这种标准库设施正确工作的基础。第一个例......
  • 07C++选择结构(1)
    一、基础知识1、关系运算符因为我们要对条件进行判断,必然会用到关系运算符:名称大于大于等于小于小于等于等于不等于符号>>=<<===!=关系表达式的值是一个逻辑值,即“真”(True)或“假”(False)。如果条件成立,其值为“真”;如果条件不成立,其值为“假”。2、逻......