首页 > 编程语言 >C++ --- 函数模板

C++ --- 函数模板

时间:2023-12-27 23:46:05浏览次数:26  
标签:函数 C++ --- 编译器 template 类型 模板

函数模板

C++的一种编程思想称为泛型编程,主要利用的技术就是模板。编写与类型无关的调用代码,是代码复用的一种手段。 模板是泛型编程的基础。C++提供两种模板机制:函数模板和类模板。

函数模板:建立一个通用的函数,它用到的参数类型可以不确定,用一个虚拟类型替代。等到函数调用的时候,根据具体传递的参数推导出真正的数据类型。

语法:

1.template <typename T>
2.函数的声明或定义

template:声明创建模板;
typename:表明其后面的符号是一种数据类型,可以用class代替;
T:通用的数据类型,名称可以替换,通常为大写字母。

 

多个类型:

template<typename T1, typename T2, typename T3>

注意:

函数模板不是一个函数,因为它不是具体要调用的某一个函数,而是一个模板;

自动类型推导,必须推导出一致的数据类型T才可以使用;模板必须要确定出T的数据类型才可以使用;

可以通过空模板实参列表< >限定编译器只匹配函数模板。

完整代码测试

#include <iostream>
 
using namespace std;
 
template <typename T>
void Swap(T& a, T& b)
{
    T tmp = a;
    a = b;
    b = tmp;
}
 
int main()
{
    int a = 10;
    int b = 20;
    Swap(a, b);    //自动推导调用
    //Swap<int>(a, b);//显示指定调用
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
 
    float c = 12.3;
    float d = 23.4;
 
    //Swap(c, d); //自动推导调用
    Swap<float>(c, d); //显示指定调用
    cout << "c = " << c << endl;
    cout << "d = " << d << endl;
}

深入理解函数模板

对于函数模板中使用的类型不同,编译器会产生不同的函数

编译器会对函数模板进行两次编译

第一次是对函数模板本身进行编译,包括语法检查等

第二次是对参数替换后的代码进行编译,这就相当于编译普通函数一样,进行类型规则检查等。

需要注意的是

编译器是无法自动推导返回值类型的;

可以从左向右部分指定类型参数。

#include <iostream>
 
using namespace std;
 
template <typename T1, typename T2, typename T3>
T1 add(T2 a, T3 b)
{
    T1 ret;
    ret = static_cast<T1>(a + b);
    return ret;
}
 
int main()
{
    int c = 12;
    float d = 23.4;
    //cout << add(c, d) << endl;    //error,无法自动推导函数返回值
    cout << add<float>(c, d) << endl;    // 从左到右部分指定函数类型
    cout << add<int, int, float>(c, d) << endl;
}

函数模板的重载

函数模板跟普通函数一样,也可以被重载

  • C++编译器优先考虑普通函数;

  • 如果函数模板可以产生一个更好的匹配,那么就选择函数模板;

#include <iostream>
 
using namespace std;
 
template <typename T>
void fun(T a)
{
    cout << "void fun(T1 a)" << endl;
}
 
template <typename T1, typename T2>
void fun(T1 a, T2 b)
{
    cout << "void fun(T1 a, T2 b)" << endl;
}
 
void fun(int a, float b)
{
    cout << "void fun(int a, float b)" << endl;
}
 
int main()
{
    int a = 0;
    float b = 0.0;
    fun(a);   
    fun(a, b);    // 普通函数void fun(int a, float b)已经能完美匹配,于是调用普通函数
    fun(b, a);    // 这个调用,函数模板有更好的匹配,于是调用函数模板
    fun<>(a, b); // 限定只使用函数模板
}

从输出可以得到,编译器会优先去调用普通函数,但是当函数模板有更好的匹配时或使用限定符<>时,编译器就会去匹配函数模板。

总结

  • 函数模板是泛型编程在C++中的应用方式之一
  • 函数模板能够根据实参对参数类型进行推导
  • 函数模板支持显示的指定参数类型
  • 函数模板是C++中重要的代码复用方式
  • 函数模板通过具体类型产生不同的函数
  • 函数模板可以定义任意多个不同的类型参数
  • 函数模板中的返回值类型必须显示指定
  • 函数模板可以像普通函数一样重载

 

标签:函数,C++,---,编译器,template,类型,模板
From: https://www.cnblogs.com/god-of-death/p/17931693.html

相关文章

  • OpenChat-3.5:70亿参数下的AI突破
    引言在对话AI的发展史上,OpenChat-3.5标志着一个新纪元的到来。拥有70亿参数的这一模型,不仅是对现有语言学习模型(LLMs)的重大改进,更是在多模态任务中树立了新的标准。模型概述OpenChat-3.5作为一款先进的多模态语言模型,凭借其卓越的编码能力和通用化方法,在各类基准测试中表现突出。在......
  • 无涯教程-Java泛型 - 有界类型
    有时您可能想限制参数的类型,如对数字进行操作的方法可能只希望接受Number或其子类的,这就是有界类型参数的用途,使用extends实现。这个示例是泛型方法,返回三个Comparable对象中的最大对象-publicclassMaximumTest{//确定三个Comparable对象中最大的一个publics......
  • device-autojs
    //设备屏幕分辨率宽度。varw=device.width;//设备屏幕分辨率高度。varh=device.height;//修订版本号,或者诸如"M4-rc20"的标识。var修订版本号=device.buildId;//设备的主板(?)型号。var设备的主板型号=device.broad;//与产品或硬件相关的厂商品牌,如"Xiaomi","Huawei......
  • ts构建编译选项-tsconfig.json
    概述如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。一个项目可以通过以下方式之一来编译:使用tsconfig.json不带任何输入文件的情况下调用tsc,编译器会从当前目录开......
  • Linux - 查看磁盘io利用率
    一、概述含义:iostat是I/Ostatistics(输入/输出统计)的缩写作用1、主要对系统的磁盘操作活动进行监视2、汇报磁盘活动及CPU使用情况,输出磁盘IO和CPU的统计信息劣势不能对某个进程进行深入分析,仅对系统的整体情况进行分析二、安装iostat属于sysstat软件包,安装iostat的命令:......
  • 内置组件-Teleport
    介绍<Teleport>是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的DOM结构外层的位置去。基本用法​有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在DOM中应该被渲染在整个Vue应用外部的其他地方......
  • 数据库专题--XQuery语句
    XQuery相对于XML的关系,等同于SQL相对于数据库表的关系。XQuery被设计用来查询XML数据-不仅仅限于XML文件,还包括任何可以XML形态呈现的数据,包括数据库。XQuery是用来从XML文档查找和提取元素及属性的语言。这是一个XQuery解决实际问题的例子:“从存储在名为......
  • c++调用c#
    c++调用c#dll(2种方式,com组件和clr工程)_c++调用c#dll-CSDN博客C++调用C#总结_clrcreateinstance-CSDN博客 以下C#的字符串和std:string之间互转:stringClr字符串转Cpp(System::String^strClr){constchar*chars=(constchar*)(System::Runtime::InteropServices::Mar......
  • 内置组件-Transition
    介绍<Transition>是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发:由v-if所触发的切换由v-show所触发的切换由特殊元素切换的动态组件改变特殊......
  • GOF23--23种设计模式(三)
    一.桥接模式Java中的桥接模式(BridgePattern)是一种结构性设计模式,它将抽象部分和实现部分分离,使它们可以独立变化,同时通过桥接对象将它们连接起来。这种模式将抽象与其实现解耦,使得抽象和实现可以独立变化。抽象和它的实现通过一个桥接类进行连接,使得它们可以各自独立地变化。......