用函数模板实现和优化抽象操作

摘要:本文介绍函数模板的概念、用途以及如何创建函数模板和函数模板的使用方 法......

在创建完成抽象操作的函数时,如:拷贝,反转和排序,你必须定义多个版 本以便能处理每一种数据类型。以 max() 函数为例,它返回两个参数中的较大者:

double max(double first, double second);
complex max(complex first, complex second);
date max(date first, date second);
//..该函数的 其它版本

尽管这个函数针对不同的数据类型其实现都是一样的,但程序员必须为 每一种数据类型定义一个单独的版本:

double max(double first, double second)
{
  return first>second? first : second;
}
complex max(complex first, complex second)
{
  return first>second? first : second;
}
date max(date first, date second)
{
  return first>second? first : second;
}

这样不但重复 劳动,容易出错,而且还带来很大的维护和调试工作量。更糟的是,即使你在程序中不使用 某个版本,其代码仍然增加可执行文件的大小,大多数编译器将不会从可执行文件中删除未 引用的函数。

用普通函数来实现抽象操作会迫使你定义多个函数实例,从而招致不小 的维护工作和调试开销。解决办法是使用函数模板代替普通函数。

使用函数模板

函数模板解决了上述所有的问题。类型无关并且只在需要时自动实例化。本文下面将 展示如何定义函数模板以便抽象通用操作,示范其使用方法并讨论优化技术。

第一步 :定义

函数模板的声明是在关键字 template 后跟随一个或多个模板在尖括弧内的参 数和原型。与普通函数相对,它通常是在一个转换单元里声明,而在另一个单元中定义,你 可以在某个头文件中定义模板。例如:

// file max.h
#ifndef MAX_INCLUDED
#define MAX_INCLUDED
template <class T> T max(T t1, T t2)
{
  return (t1 > t2) ? t1 : t2;
}
#endif

<class T> 定义 T 作为模板参数,或者是占位符,当实例化 max()时,它将替代具体的数据类型。max 是函数名,t1和t2是其参数,返回值的类型为 T。 你可以像使用普通的函数那样使用这个 max()。编译器按照所使用的数据类型自动产生相应 的模板特化,或者说是实例:

int n=10,m=16;
int highest = max(n,m); // 产生 int 版本
std::complex<double> c1, c2;
//.. 给 c1,c2 赋值
std::complex<double> higher=max(c1,c2); // complex 版本

时间: 2024-12-21 12:50:26

用函数模板实现和优化抽象操作的相关文章

函数模板 结构体数组-C++中带有数组参数的函数模板是否可以实例化为结构体数组类型来进行比较等操作?

问题描述 C++中带有数组参数的函数模板是否可以实例化为结构体数组类型来进行比较等操作? 不管什么类型的数组,都有一些类似的操作,因此可以使用函数模板实现代码复用.但是我在实现"查找"功能时不知道怎么处理结构体数组.要保证函数模板不仅适用于结构体数组,还适用于其他数组.求助各位大神! #include using namespace std; #define N 10 struct stu { int num; double score; }; /*查找:查找某元素,返回其下标*/ t

opencv笔记4:模板运算和常见滤波操作

time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工程--图像处理>(章毓晋)一书第3章,空域增强:模板操作.同时也有个疑问:此书第四章,频域图像增强,讲了低通滤波和高通滤波,然而这些东西和模板运算中的平滑.锐化操作有什么区别?... 以下是正文: 模板运算 首先我们把所有图像看作矩阵. 模板一般是nxn(n通常是3.5.7.9等很小的奇数)的矩阵.模板

C++中函数模板(function template) 的 推进(forward) 问题

函数模板在调用函数的时候, 由于实参(argument)转换形参(parameter)的时候, 会发生改变, 导致无法保留原实参的信息, 即推进(forward)问题; 主要包括: 引用和右值;引用, 即因为模板参数非引用, 导致复制操作, 无法提供引用类型;右值, 即因为模板参数只能转换为左值, 无法提供右值; 解决方法: 引用: 使用右值参数(T&& t), 可以保证传递引用不发生改变; 右值:使用右值参数, 再使用forward()函数(#include<utility>

一个排序用的C++函数模板

前段时间编写MFC程序时,需要对一个字符串集合CStringArray进行排序.标准模板库STL提供的函数模板sort虽然功能强大,但有两个不便: 1. sort使用枚举器(iterator)机制处理C++数组(即指针)和诸如vector这样的STL对象,但MFC集合类CArray.CStringArray没有提供枚举器.虽然可以通过集合类的成员函数GetData把集合转换成指针,然后调用sort进行处理,但这样做破坏了对象的封装性. 2.如果使用降序排序,还需要另外编一个比较函数. 为此我自己

【C/C++学院】0814-引用高级、引用高级增加/auto自动变量自动根据类型创建数据/Bool/Enum/newdelete全局/大数据乘法与结构体/函数模板与auto/宽字符本地化/inline

引用高级.引用高级增加 #include<iostream> #include<stdlib.h> // int a[10] // int (&ra)[10] // int a[2][5] // int (&ra)[2][5] void main1() { int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int(&ra)[10](a);//引用就是给原来的变量有一个别名同一个地址 int i = 0; for (

C++中函数模板的用法详细解析_C 语言

定义 我们知道函数的重载可以实现一个函数名多用,将功能相同或者类似函数用同一个名来定义.这样可以简化函数的调用形式,但是程序中,仍然需要分别定义每一个函数. C++提供的函数模板可以更加简化这个过程. 所谓函数模板实际上是建立一个通用函数,其涵涵素类型额形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板. 凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需要在模板中定义一次即可.在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能

用函数模板,写一个简单高效的 JSON 查询器的方法介绍_javascript技巧

JSON可谓是JavaScript的亮点,它能用优雅简练的代码实现Object和Array的初始化.同样是基于文本的数据定义,它比符号分隔更有语义,比XML更简洁.因此越来越多的JS开发中,使用它作为数据的传输和储存. JS数组内置了不少有用的方法,方便我们对数据的查询和筛选.例如我们有一堆数据: 复制代码 代码如下: var heros = [        // 名============攻=====防=======力量====敏捷=====智力====        {name:'冰室女巫

《C++ Templates中文版》——2.1 初探函数模板

2.1 初探函数模板 函数模板提供了一种函数行为,该函数行为可以用多种不同的类型进行调用:也就是说,函数模板代表一个函数家族.它的表示(即外形)看起来和普通的函数很相似,唯一的区别就是有些函数元素是未确定的:这些元素将在使用时被参数化.为了阐明这些概念,让我们先来看一个简单的例子. 2.1.1 定义模板下面就是一个返回两个值中最大者的函数模板: //basics/max.hpp template <typename T> inline T const& max (T const&

求变量的数据类型,typeid,bool,C和C++的不同,new和delete,C++中的枚举,inline和可变参数模板,auto和函数模板,宽字符

求变量的数据类型,通过函数typeid(变量名).name();获得变量的数据类型. 案例如下: #include<iostream> #include<stdlib.h>   voidmain() {    doubledb = 10.9;    double *pdb = &db;    autonum =pdb;    //通过typeid的方式获得数据类型    std::cout << typeid(db).name() << std::e