简单掌握C++中的函数模板

 更新时间:2016年04月09日 11:47:02   作者:BeyondHaven  
这篇文章主要介绍了C++中的函数模板,包括函数模板的声明和生成以及异常处理等基本知识,需要的朋友可以参考下

1.函数模板的声明和模板函数的生成
1.1函数模板的声明
函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。它的最大特点是把函数使用的数据类型作为参数。
函数模板的声明形式为:
template<typename 数据类型参数标识符>

<返回类型><函数名>(参数表)
{
  函数体
}

其中,template是定义模板函数的关键字;template后面的尖括号不能省略;typename(或class)是声明数据类型参数标识符的关键字,用以说明它后面的标识符是数据类型标识符。这样,在以后定义的这个函数中,凡希望根据实参数据类型来确定数据类型的变量,都可以用数据类型参数标识符来说明,从而使这个变量可以适应不同的数据类型。例如:

template<typename T>
T fuc(T x, int y)
{
  T x;
  //……
}

如果主调函数中有以下语句:

double d;
int a;
fuc(d,a);

则系统将用实参d的数据类型double去代替函数模板中的T生成函数:

double fuc(double x,int y)
{
  double x;
  //……
}

函数模板只是声明了一个函数的描述即模板,不是一个可以直接执行的函数,只有根据实际情况用实参的数据类型代替类型参数标识符之后,才能产生真正的函数。
关键字typename也可以使用关键字class,这时数据类型参数标识符就可以使用所有的C++数据类型。
1.2.模板函数的生成
函数模板的数据类型参数标识符实际上是一个类型形参,在使用函数模板时,要将这个形参实例化为确定的数据类型。将类型形参实例化的参数称为模板实参,用模板实参实例化的函数称为模板函数。模板函数的生成就是将函数模板的类型形参实例化的过程。例如:
使用中应注意的几个问题:
(1)函数模板允许使用多个类型参数,但在template定义部分的每个形参前必须有关键字typename或class,即:
template<class 数据类型参数标识符1,…,class 数据类型参数标识符n>

<返回类型><函数名>(参数表)
{
   函数体
}

(2)在template语句与函数模板定义语句<返回类型>之间不允许有别的语句。如下面的声明是错误的:
template<class T>
int I;
T min(T x,T y)
{
  函数体
}

(3)模板函数类似于重载函数,但两者有很大区别:函数重载时,每个函数体内可以执行不同的动作,但同一个函数模板实例化后的模板函数都必须执行相同的动作。

2 函数模板的异常处理
函数模板中的模板形参可实例化为各种类型,但当实例化模板形参的各模板实参之间不完全一致时,就可能发生错误,如:

template<typename T>    
void min(T &x, T &y)
{ return (x<y)?x:y; }
void func(int i, char j)
{
  min(i, i);
  min(j, j);
  min(i, j);
  min(j, i);
}

例子中的后两个调用是错误的,出现错误的原因是,在调用时,编译器按最先遇到的实参的类型隐含地生成一个模板函数,并用它对所有模板函数进行一致性检查,例如对语句

min(i, j);

先遇到的实参i是整型的,编译器就将模板形参解释为整型,此后出现的模板实参j不能解释为整型而产生错误,此时没有隐含的类型转换功能。解决此种异常的方法有两种:
(1)采用强制类型转换,如将语句min(i, j);改写为min(i,int( j));
(2)用非模板函数重载函数模板
方法有两种:
(1)借用函数模板的函数体
此时只声明非模板函数的原型,它的函数体借用函数模板的函数体。如改写上面的例子如下:
template<typename T>      

void min(T &x, T &y)
{ return (x<y)?x:y; }
int min(int,int);
void func(int i, char j)
{
  min(i, i);
  min(j, j);
  min(i, j);
  min(j, i);
}

执行该程序就不会出错了,因为重载函数支持数据间的隐式类型转换。
(2)重新定义函数体
就像一般的重载函数一样,重新定义一个完整的非模板函数,它所带的参数可以随意。C++中,函数模板与同名的非模板函数重载时,应遵循下列调用原则:
• 寻找一个参数完全匹配的函数,若找到就调用它。若参数完全匹配的函数多于一个,则这个调用是一个错误的调用。
• 寻找一个函数模板,若找到就将其实例化生成一个匹配的模板函数并调用它。
• 若上面两条都失败,则使用函数重载的方法,通过类型转换产生参数匹配,若找到就调用它。
•若上面三条都失败,还没有找都匹配的函数,则这个调用是一个错误的调用。

3.小例子

#include <iostream> 
#include <string> 
using namespace std; 
 
template<class T> void swap(T *x, T *y){//函数的模板,只要能使用等号赋值类型都可以用这个模板互换 
  T temp = *x; 
  *x = *y; 
  *y = temp; 
} 
 
void main(){ 
  int i = 9, j = 5; 
  float k = 9.2, l = 5.6; 
  swap(&i, &j);//交换整形 
  swap(&k, &l);//交换浮点型 
  cout<<"i = "<<i<<" , j = "<<j<<endl; 
  cout<<"k = "<<k<<" , l = "<<l<<endl; 
} 

相关文章

  • 深入了解C语言结构化的程序设计

    深入了解C语言结构化的程序设计

    这篇文章主要介绍了C语言编程中程序的一些基本的编写优化技巧,文中涉及到了基础的C程序内存方面的知识,非常推荐!需要的朋友可以参考下
    2021-07-07
  • C语言利用goto语句设计实现一个关机程序

    C语言利用goto语句设计实现一个关机程序

    今天给大家分享一个非常有趣的知识——用goto语句编写一个关机小程序。主要用到了shutdown命令语句、goto语句、strcmp函数等知识点,感兴趣的可以了解一下
    2023-01-01
  • VS编译出现MSB3073命令的解决方案

    VS编译出现MSB3073命令的解决方案

    =error MSB3073是Visual Studio编译器报出的错误,本文主要介绍了VS编译出现MSB3073命令的解决方案,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • C++实现LeetCode(43.字符串相乘)

    C++实现LeetCode(43.字符串相乘)

    这篇文章主要介绍了C++实现LeetCode(43.字符串相乘),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ 右值语义相关总结

    C++ 右值语义相关总结

    这篇文章主要介绍了C++ 右值语义的的相关资料,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下
    2021-02-02
  • C++ 命名空间避免命名冲突的实现

    C++ 命名空间避免命名冲突的实现

    命名空间是C++中用来避免命名冲突的一种机制,本文主要介绍了C++ 命名空间避免命名冲突的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • C语言中指针和数组试题详解分析

    C语言中指针和数组试题详解分析

    变量存放在内存中,内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。数据对象是指存储在内存中的一个指定数据类型的数值或字符串,它们都有一个自己的地址,指针是保存这个地址的变量
    2021-10-10
  • C++程序内存栈区与堆区模型案例分析

    C++程序内存栈区与堆区模型案例分析

    一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢,让我们一起来看看
    2022-03-03
  • C/C++实现发送与接收HTTP/S请求的示例代码

    C/C++实现发送与接收HTTP/S请求的示例代码

    HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的协议,它是一种无状态的、应用层的协议,用于在计算机之间传输超文本文档,通常在 Web 浏览器和 Web 服务器之间进行数据通信,本文给大家介绍了C/C++发送与接收HTTP/S请求,需要的朋友可以参考下
    2023-11-11
  • C++ main函数的几点细节

    C++ main函数的几点细节

    这篇文章主要介绍了C++ main函数的几点细节,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下
    2020-08-08

最新评论