1.参数类型

  1. template <typename T> void f1(T&);//实参必须是左值
  2. f1(i);//对
  3. f1(ci);//对,T的类型是const int
  4. f1();//错
  5. template <typename T> void f2(const T&);//实参可以是左值,const右值
  6. f2(i);//对
  7. f2(ci);//对
  8. f2();//对
  9. template <typename T> void f3(T&&);//实参只能是非const右值

2.右值引用参数的模版函数

  1. template <typename T> void f3(T&& val)
  2. {
  3. T t=val;//拷贝还是绑定一个引用?
  4. t=fcn(t);//赋值只改变t还是t和val都变?
  5. if (val == t)//若t是引用类型,则一直为true
  6. ……
  7. }
  8. //看传入的值
  9. .如果传入值是右值,如字面常量,Tint。此时t的类型也为int,通过val初始化,参数val保持不变
  10. .如果传入值是左值,Tint&???此时t的类型也为int&,则变t也变val

3.标准库的move

  1. template <typename T> typename remove_reference<T>::type&& move(T&& t)
  2. {
  3. return static_cast<typename remove_reference<T>::type&&>(t);
  4. }

std::move (string("bye!"))执行过程:

  • 推断T的类型为string
  • remove_reference用string实例化
  • remove_reference<string>的type成员是string
  • move的返回类型是string&&
  • move的函数参数t的类型为string&&

4.转发的类型保持

  1. template <typename F, typename T1, typename T2> void flip1(F f,T1 t1,T2 t2)
  2. {
  3. f(t2,t1);
  4. }
  5. void f(int v1, int &v2)
  6. {
  7. }
  8. //
  9. f(,i)
  10. flip1(f,j,);//没有发挥引用的效果

解决办法:模版类型参数是右值引用,对应实参的const属性和左右值属性得到保持。为什么?引用折叠。

  1. template <typename F, typename T1, typename T2> void flip1(F f,T1&& t1,T2&& t2)
  2. {
  3. f(t2,t1);
  4. }

还有个问题:

flip(g,i,42);//不能从一个左值实例化int &&

解决办法:

  1. template <typename F, typename T1, typename T2> void flip1(F f,T1&& t1,T2&& t2)
  2. {
  3. f(std::forward<T2>(t2),std::forward<T1>(t1));//显式模版实参类型
  4. }

4.模版重载

  1. //1.
  2. template <typename T> string debug_rep(const T& t)
  3. {
  4. stream ret;
  5. ret<<t;
  6. return ret.str();
  7. }
  8. //2.
  9. template <typename T> string debug_rep(T* p)
  10. {
  11. stream ret;
  12. ret<<"pointer is: "<<p;
  13. if (p)
  14. ret<<" "<<debug_rep(*p);
  15. else
  16. ret<<" null ptr"<<;
  17. return ret.str();
  18. }
  19. //调用
  20. string s("hi");
  21. cout<<debug_rep(s)<<endl;//只有第一个版本可行
  22. cout<<debug_rep(&s)<<endl;//第一个版本实例化为:debug_rep(const string*&), T类型为string*
  23. //第二个版本实例化为:debug_rep(string*),T类型为string  更精确,编译器选择第二个
  24.  
  25. const string *sp=&s;
  26. cout<<debug_rep(sp)<<endl;//第一个版本实例化为:debug_rep(const string*&), T类型为string*
  27. //第二个版本实例化为:debug_rep(const string*),T类型为const string,更特列化,选择第二个

一个非函数模版和一个函数模版都能提供同样的匹配时,编译器选择非函数模版。

多个函数模版提供同样的匹配时,编译器选择最特例化的那个。

5.可变函数模版

  1. template <typename T, typename ... Args> viod foo(const T& t, const Args& ... rest)
    {
      cout<<sizeof...(Args)<<endl;//类型参数的数目
      cout<<sizeof...(rest)<<endl;//函数参数的数目
    }
  2. //
  3. int i=; double d=3.14; string s="stringiest ";
  4. foo(i,s,,d);  //参数包有3个参数
  5. foo(s,,"hi"); //参数包有2个参数
  6. foo(d,s);    //参数包有1个参数
  7. foo("hi");   //参数包有0个参数
  8. //实例化版本
  9. void foo(const int&, const string&, const int&, const double&);
  10. void foo(const string&, const int&, const char[]&);
  11. void foo(const double&, const string&);
  12. void foo(const char[]&);

递归调用:必须声明一个非可变参数版本,否则无限递归

  1. template<typename T> ostream &print(ostream &os, const T& t)//打印最后一个元素
  2. {
  3. return os<<t;
  4. }
  5. template <typename T, typename... Args> ostream &print(ostream& os, const T& t, const Args&... rest)
  6. {
  7. os<<t<<",";
  8. return print(os, rest ...);//递归调用
  9. }

5.1 扩展

5.2 转发(forward)

6.模版特例化:本质上实例化一个模板,而不是重载,不影响函数匹配

  1. template <typename T> int compare(const T&, const T&);
  2. template <size_t N, size_t M> int compare(const char (&)[N],const char (&)[M]);
  3. const char* p1="hi",*p2="mom"
  4. compare(p1,p2);//调用第一个版本
  5. compare("hi","mom");//调用两个版本
  6.  
  7. template <> int compare(const char* const &p1, const char* const &p2)
  8. {
  9. return strcmp(p1,p2);
  10. }
  11. //此特例化,是为了处理字符指针,而不是数组

模版及其特例化版本应声明在同一个头文件中,同名模版的声明应放在前面,然后是这些模版的特例化版本。

6.1 类模板特列化

6.2 类模板部分特列化

C++——模板的更多相关文章

  1. Jade模板引擎让你飞

    写在前面:现在jade改名成pug了 一.安装 npm install jade 二.基本使用 1.简单使用 p hello jade! 渲染后: <p>hello jade!</p ...

  2. ABP入门系列(2)——通过模板创建MAP版本项目

    一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包: 设置以Web结尾的项目,设置为启动项目: 打 ...

  3. CMS模板应用调研问卷

    截止目前,已经有数十家网站与我们合作,进行了MIP化改造,在搜索结果页也能看到"闪电标"的出现.除了改造方面的问题,MIP项目组被问到最多的就是:我用了wordpress,我用了织 ...

  4. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  5. 【原创分享·微信支付】C# MVC 微信支付之微信模板消息推送

    微信支付之微信模板消息推送                    今天我要跟大家分享的是“模板消息”的推送,这玩意呢,你说用途嘛,那还是真真的牛逼呐.原因在哪?就是因为它是依赖微信生存的呀,所以他能不 ...

  6. OpenCV模板匹配算法详解

    1 理论介绍 模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标.OpenCV ...

  7. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  8. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

  9. ThinkPHP 模板substr的截取字符串函数

    ThinkPHP 模板substr的截取字符串函数在Common/function.php加上以下代码 /** ** 截取中文字符串 **/ function msubstr($str, $start ...

  10. DDD领域驱动设计 - 设计文档模板

    设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...

随机推荐

  1. 测开之路三十:Flask基础之jinja2模板继承

    实现某些位置的内容固定,某些位置的内容动态展示,如: 中文文档地址:http://docs.jinkan.org/docs/jinja2/templates.html#template-inherit ...

  2. latex的资料ftp

    ftp://ftp.tex.ac.uk/ctan/tex-archive/ ftp ftp.tex.ac.uk anonymous ls

  3. PAT 2019-3 7-1 Sexy Primes

    Description: Sexy primes are pairs of primes of the form (p, p+6), so-named since "sex" is ...

  4. linux 部署系统通过SecureCRT启动tomcat 控制台中文乱码

    查资料又是查了半天 首先 查看linux 当前系统字符集命令 echo $LANG 查看linux 当前系统语言 locale 网上说的又是下中文包,又是改临时语言,这些不能一概而论,我也觉得我不是中 ...

  5. PHP 算式验证码

    这里不多说,直接上代码! /** * 改造的加减法验证类 * 使用示例 VerifyCode::get('xxx', 20); * 验证示例 VerifyCode::check('1', 'xxx') ...

  6. 【转】C++ STL中常见容器的时间复杂度

    map, set, multimap, and multiset 上述四种容器采用红黑树实现,红黑树是平衡二叉树的一种.不同操作的时间复杂度近似为: 插入: O(logN) 查看:O(logN) 删除 ...

  7. struts2之ModelDriven

    在Struts 2中,提供了另外一种直接使用领域对象的方式,就是让action实现com.opensymphony. xwork2.ModelDriven接口.ModelDriven让你可以直接操作应 ...

  8. js转换成数字

    /** * 转换成数字,有两种方法: * 1.Number(var) * 2.parseInt(var)与parseFloat(var) */ // 字符串转换成数字 // 纯字母 var foo = ...

  9. NHibernet Unable to locate persister for the entity

    第一 xml文件必须为 *.hbm.xml 第二  设置xml文件为嵌入的资源,用鼠标点击右键 然后生成操作里 选择嵌入的资源即可解决. https://www.cnblogs.com/lyj/

  10. android jni控制gpio (rk3288)

    1.添加驱动程序 2.编写jni c程序编译为库给java调用 3.app调用jni静态链接库操作底层驱动 1.添加驱动程序 修改/work/rk3288/firefly-rk3288_android ...