C++.Templates学习总结归纳1

函数模板

首先我们来看看函数模板,一个函数模板(function template)代表一族函数,其表现和一般的函数一样,只是其中的某些元素在编写的时候还不知道,也就是说这些还不知道的元素,我们将其参数化了。

例如下面的返回两个数中的较大者:

template<class T>
inline T const& max(T const& a,T const& b){return a>b?a:b;
}

当然,上述代码中的class也可以用typename所代替,但是不能使用struct代替。不过一般建议使用typename。

举个可以实际运行的例子:

#include <iostream>
#include <string>template<class T>
inline T const& max(T const& a,T const& b){return a>b?a:b;
}int main(){std::cout<< ::max(2,1)<<std::endl;std::cout<< ::max(1.12,4.5)<<std::endl;std::string str1="hello";std::string str2="rollen";std::cout<< ::max(str1,str2)<<std::endl;return 0;
}

  注意上面使用了::max,是为了和std::max进行区分的。

但是如果试图使用某一类型的时候,但是这个类型中并没有定义我们在模板函数中所使用的某一些操作的时候,就会出现错误。

std::complex<float> c1,c2;max(c1,c2);

上面的代码在编译期间就会出现错误。

实际上,我们的template会被编译两次:

第一次:主要是对代码进行语法检查,比如缺少分号,什么的。

第二次: 主要是对template代码中所进行的操作进行检查,就如同上面的那样,是否使用了未定义的操作等等。

其实这样会导致一些问题的,我们在后面的内容中会探讨这个问题。

template<class T>
inline T const& max(T const& a,T const& b){return a>b?a:b;
}std::cout<< ::max(2,1)<<std::endl;   //编译器可以推导出是两个int
std::cout<< ::max(1.12,4.5)<<std::endl;  //编译器可以推到出是两个double
//std::cout<< ::max(1 , 1.2)<<std::endl;   //这条错误

函数模板的参数分为两种:template parameter和call parameter参数两种。比如对于上面的max代码,其中的T是template parameter参数,a,b是call parameter参数。前者的数量可以是任意的,但是你不能在函数模板中为他们设定初始值,这一点和class template是不一样的,后面会提到。

对于上面代码中的那一条错误语句,其实你可以改为下面的语句:

std::cout<< ::max<double>(1 , 1.2)<<std::endl; 

但是如果template parameter和call parameter参数没有明显的联系的时候,并且编译器无法推断出template parameter的时候,你就需要明确的指定template argument,例如你可以在max中引入第三个template argument type 作为返回类型:

template<typename T1,typename T2,typename RT>
inline RT max(T1 const& a, T2 const& b);max<int,double,double>(1,2.3);

但是这样的话,需要在max的尖括号中写3个参数,其实我们至于要改变一些RT的顺序,就可以只需要写一个参数就行了:

template<typename RT,typename T1,typename T2>
inline RT max(T1 const& a, T2 const& b);max<double>(1,2.3);

 在这个例子中,只要我们明确的指出返回类型,然后编译器就可以自动推断出a和b的类型; 

关于模板函数的重载问题:

首先来看看一个小例子:

#include <iostream>
#include <string>
#include <cstring>template<class T>
inline T const& max(T const& a, T const& b){std::cout<<"inline T const& max(T a, T b)"<<std::endl;return a>b ? a :b;
}template<class T>
inline T* const& max(T* a, T* b){std::cout<<"inline T* const& max(T* a, T* b)"<<std::endl;return *a > *b ?a: b;
}inline char const* const& max(char const* const& a, char const* const& b){std::cout<<"inline char const* const& max(char const* const& a, char const* const& b)"<<std::endl;return std::strcmp(a,b)<0?b:a;
}int main(){int a=1,b=2;::max(a,b);std::string str1="hello";std::string str2="rollen";::max(str1,str2);int* pa=&a;int* pb=&b;::max(pa,pb);char const* s1="hello";char const* s2="rollen";::max(s1,s2);return 0;
}

运行结果为:

大家可以注意编译器优先选择那些特化的模板。

另外建议大家在重载函数模板的时候,不同的重载形式之间最好存在绝对必要的差别,并且请把所有形式的重载函数写在他们的被调用点之前。


转载于:https://www.cnblogs.com/rollenholt/archive/2012/03/07/2383475.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xml Tips

Xml Tips//z 2012-3-7 16:43:47 PM IS2120CSDN1. xml 中的注释<!-- 这是注释 -->并非用于 XML 分析器的内容&#xff08;例如与文档结构或编辑有关的说明&#xff09;可以包含在注释中。注释以 <!-- 开头&#xff0c;以 --> 结尾&#xff0c;例如<!--catalog la…

Window7+vs2008+QT环境搭建

记录下自己是如何搭建QT开发环境的&#xff0c;备忘吧。操作系统&#xff1a;win7&#xff0c;其实winXP&#xff0c;win7都没有关系&#xff1b;我使用的机器安装的操作系统是win7&#xff1b;开发环境是VS&#xff0c;使用2005,2008,2010或者即将发布的2011都行&#xff1b;因…

Javascript创建对象的几种方式?

javascript 中常见的创建对象的几种方式&#xff1a; 1. 使用Object构造函数创建&#xff1b; 使用Object构造函数来创建一个对象&#xff0c;下面代码创建了一个person对象&#xff0c;并用两种方式打印出了Name的属性值。 var person new Object(); person.name"kevin&…

使用 RMAN 同步数据库

使用 RMAN 同步数据库使用 RMAN 同步数据库一&#xff0e;概述二 操作步骤(一)&#xff0e;把生产库置为归档模式(二).启动rman做数据库0级备份(三)&#xff0e;修改生产库数据库到未归档(四)&#xff0e;拷贝备份集到测试库(五).在测试库上的操作一&#xff0e;概述 因项目组遇…

js实现图片上传预览及进度条

js实现图片上传预览及进度条 原文js实现图片上传预览及进度条 最近在做图片上传的时候&#xff0c;由于产品设计的比较fashion&#xff0c;上网找了比较久还没有现成的&#xff0c;因此自己做了一个&#xff0c;实现的功能如下&#xff1a; 1&#xff1a;去除浏览器<input …

webapi文档描述-swagger

最近做的项目使用mvcwebapi&#xff0c;采取前后端分离的方式&#xff0c;后台提供API接口给前端开发人员。这个过程中遇到一个问题后台开发人员怎么提供接口说明文档给前端开发人员,最初打算使用word文档方式进行交流&#xff0c;实际操作中却很少动手去写。为了解决这个问题&…

《推荐系统实践》样章:如何利用用户标签数据

《推荐系统实践》样章&#xff1a;如何利用用户标签数据 推荐系统的目的是联系用户的兴趣和物品&#xff0c;这种联系需要依赖于不同的媒介。GroupLens在文章1中认为目前流行的推荐系统基本上通过三种方式来联系用户兴趣和物品。如图1所示&#xff0c;第一种方式是通过用户喜欢…

STM32 基于正电原子开发板,改换芯片为STM32F103R6,Proteus仿真的一些问题

最近在学STM32&#xff0c;网上收集了一些信息&#xff0c;最后用正点原子的开发板来学习。 MDK的配置请参考原子哥的资料&#xff0c;我主要的学习方法是参考原子哥的开发板与实验案例&#xff0c;改换不一样的芯片&#xff0c;也要做出的一样的效果。但在最基础的入门就遇到…

深入理解闭包系列第二篇——从执行环境角度看闭包

前面的话 本文从执行环境的角度来分析闭包&#xff0c;先用一张图开宗明义&#xff0c;然后根据图示内容对代码进行逐行说明&#xff0c;试图对闭包进行更直观的解释 图示 说明 下面按照代码执行流的顺序对该图示进行详细说明 function foo(){var a 2;function bar(){console.…

VS2017 调用Tesseract

最近在学tesseract&#xff0c;但遇到太多的问题是。 虽然网上有不少的方法&#xff0c;就算是按照tersseract&#xff0c;github上提供的方法也是编译不成功。 问题一大堆。不过我也想到了其它方法最张还是可以用了。 我有2个方法&#xff0c; 方法1, 1&#xff0c;先build t…

在windows上安装OpenCV

在windows上安装OpenCV&#xff0c;官方提供的教程&#xff0c;我翻译了一下。如有不正解&#xff0c;请指正 使用git-bash&#xff08;版本> 2.14.1&#xff09;和cmake&#xff08;版本> 3.9.1&#xff09;安装 1.您必须下载cmake&#xff08;版本> 3.9.1&…

CMake 编译 OpenCV 项目,不是编译OpenCV, 用了之后才知道CMake也太好用了。

新建一个 CMakeList.txt 复制下面代码&#xff0c;并保存 cmake_minimum_required (VERSION 3.0)PROJECT(Chapter2)set (CMAKE_CXX_STANDARD 11)IF(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)conan_basic_setup() E…

Java Ajax jsonp 跨域请求

2019独角兽企业重金招聘Python工程师标准>>> 1. 什么是JSONP 一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通&#xff0c;而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略&#xff0c;网页…

对IEnumerableT,IDictionaryTkey,TValue,ICollectionT,IListT的总结

1、IEnumerable<T>接口和IEnumerable接口 实现了IEnumerable接口的集合表明该集合能够提供一个enumerator(枚举器)对象&#xff0c;支持当前的遍历集合。IEnumerable接口只有一个成员GetEnumerator()方法。 IEnumerator接口实现了IEnumerator接口的集合实现了从一个元素到…

学习Python中用numpy与matplotlib遇到的一些数学函数与函数的绘图

学习Python中的一些数学函数与函数的绘图 主要用到numpy 与 matplotlib 如果有什么不正确&#xff0c;欢迎指教。 图片不知道怎样批量上传&#xff0c;一个一个怎么感觉很小&#xff0c;请见谅 自行复制拷贝&#xff0c;到vs&#xff0c;jupyter notebook, spyder都可以 函…

有这个OCR程序,不用再买VIP了,Python 调用百度OCR API

最近学习&#xff0c;很多东西都是视频&#xff0c;截图后&#xff0c;又想做成文档保存起来。 刚开始不多&#xff0c;打一下字就很快解决了。 随着时间的推移&#xff0c;现在越来越多的图了&#xff0c;管理起来确实不方便&#xff0c;打字有时也不能很快的解决。 所以就…

linux常用命令_Linux常用命令全称

从事IT行业的很多人都会使用Linux常用命令&#xff0c;但是知道这些常用命令全称的人并不多&#xff0c;让我们来看看这些常用命令对应的全称吧&#xff01;必备Linux命令和C语言基础_C语言_嵌入式开发工程师-创客学院​www.makeru.com.cnpwd:print work directory 打印当前目录…

存储程序(1)——MYSQL

MySQL支持把几种对象存放在服务器端供以后使用。这几种对象有一些可以根据情况通过程序代码调用&#xff0c;有一些会在数据表被修改时自动执行&#xff0c;还有一些可以在预定时刻自动执行。它们包括以下几种: 1.存储函数(stored function)。返回一个计算结果&#xff0c;该结…

闯过这 54 关,点亮你的 Git 技能树 (五) - 完结篇

这是一个系列文章&#xff0c;介绍学习 Git 的一个小游戏 - githug&#xff0c;如果你是第一次看到&#xff0c;请先阅读&#xff1a;闯过这 54 关&#xff0c;点亮你的 Git 技能树闯过这 54 关&#xff0c;点亮你的 Git 技能树&#xff08;一&#xff09;闯过这 54 关&#xf…

Jupyter notebook 不安装主题,通过修改css更改 默认字体,字体大小等

目标&#xff1a; Jupyter notebook 又不想改更主题的的情况下&#xff0c;可以通过修改css的目的来达到修改默认的字体&#xff0c;字号心达到可以好的阅读效果。 方法 要修改的css文件目录如下&#xff0c; D:\Anaconda\Lib\site-packages\notebook\static\custom 这个就是…