C++ Templates (1.4 默认模板实参 Default Template Arguments)
1.4 默认模板实参 Default Template Arguments
可以为模板参数定义默认值,这些值被称为默认模板实参(default template arguments),并且可以用于任何类型的模板[1]
比如:当需要组合不同的方法来定义返回类型使其具有不同参数类型的能力(如前一节所述),可以引入模板参数RT作为返回类型,并使RT成为两个调用实参的共同类型作为默认值。同样,有多个选择:
- 直接使用运算operator ? :。然而,由于不得不在调用参数a和b声明之前使用运算operator ? :,因此仅仅可以使用他们的类型:
basics/maxdefault1.hpp
#include <type_traits>
template <typename T1, typename T2,
typename RT = std::decay_t<decltype(true ? T1() : T2())>>
RT max(T1 a, T2 b)
{
return b < a ? a : b;
}
注意到此处使用了std::decay_t<> 用于确保不会返回引用[2]。
此实现需要传入参数的默认构造函数能够被调用。这里有另外一个解决方案,使用std::declval,但这使得声明更加复杂。第11.2.3中参考另一个例子。
- 使用类型属性中的std::common_type<>来指定返回类型的默认值:
// basics/maxdefault3.hpp
#include <type_traits>
template <typename T1, typename T2,
typename RT = std::common_type_t<T1, T2>>
RT max(T1 a, T2 b)
{
return b < a ? a : b;
}
同样请注意std::common_type<>会发生退化,因此返回值不会是一个引用。在任何情况下,调用者可以使用返回类型的默认值:
auto a = max(4, 7.2);
或者在显式指定其他模板实参类型后指定返回类型:
auto b = ::max<double, int, long double>(7.2, 4);
然而,这又有新的问题:仅仅为了指定返回类型,这需要指定3个类型。另一种替代方法需要这样一种能力:将返回类型作为第一个模板参数,但依然能够从其他模板实参中推断出该模板参数类型。理论上,前面的模板参数有默认实参而后面的模板参数没有默认实参:
template <typename RT = long, typename T1, typename T2>
RT max(T1 a, T2 b)
{
return b < a ? a : b;
}
使用该定义,可以如此调用:
int i;
long l;
...
max(i, l); // 返回long(模板参数的默认实参作为返回类型)
max<int>(4, 42); // 显式指定返回int类型
然而,这种方法只有在当模板参数具有自然的默认值的情况下才有意义(this approach only make sense, if there is a "natural" default for a template parameter)。但此处,模板参数的默认实参需要依赖于之前的模板参数。理论上,这是可能的,正如第26.5.1中所讨论的,但这依赖于类型特性,并使得定义变得复杂。
基于以上原因,最好的、最简单的解决方案便是让编译器推断返回类型,如1.3.2节所述。
脚注
C++ Templates (1.4 默认模板实参 Default Template Arguments)的更多相关文章
- C++ Templates (1.2 模板实参推断 Template Argument Deduction)
返回完整目录 目录 1.2 模板实参推断 Template Argument Deduction 1.2 模板实参推断 Template Argument Deduction 当调用函数模板(如max ...
- discuz默认模板文件结构详解-模板文件夹介绍
| — template — default 系统内置风格模板(默认风格)| — template — default – discuz_style_default.xml 风格安装文件,可用 ...
- phpcms V9 默认模板文件目录结构_PHPCms教程
PHPCMSV9 默认模板目录结构 templates 框架系统模板目录 announce 公告 show.html 内容页 ...
- django默认模板引擎和jinja2模板引擎
在使用中,大家会发现django默认模板引擎有很多局限性,最明显的就是四则运算.就只能加减,乘除都不支持.另外还有判断相等,不能直接if,要用ifequal.确实不太方便.还有一点,django默认模 ...
- eclipse - 新建jsp页面默认模板设置
有时候我们自己如果没有现成的JSP模板时,系统一般会自动生成如下页面: 这个页面显然并不是我们所需要的,所以我们需要修改默认模板 进入 修改 <%@ page language="ja ...
- grunt-init 默认模板目录更正
grunt-init是依赖grunt项目管理的脚手架工具,各种优点无须赘述,默认的template路径的作用:可以把自定义或其他模板放置其中,应用的时候直接调用模板名,不用每次寻找路径: 在安装gru ...
- Nuxt的默认模板和默认布局
Nuxt为我们提供了超简单的默认模版订制方法,只要在根目录下创建一个app.html就可以实现了 注:建立了默认模板后,记得要重启服务器,否则你的显示不会成功 默认布局主要针对于页面的统一布局使用.它 ...
- C++ Templates (2.1 类模板Stack的实现 Implementation of Class Template Stack)
返回完整目录 目录 2.1 类模板Stack的实现 Implementation of Class Template Stack 2.1.1 声明类模板 Declaration of Class Te ...
- SQL Server 默认跟踪(Default Trace)
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 基础知识(Rudimentary Knowledge) 查看默认跟踪信息(Default Tr ...
随机推荐
- vue学习(八) vue中样式 class 定义引用
//style<style> .red{ color:red; } .thin{//字体粗细 font-weight:200 } .italic{//字体倾斜 font-style:ita ...
- liunx安装和部署nacos配置中心
1.下载https://github.com/alibaba/nacos/releases nacos-server-1.3.1.tar.gz 源码包2.上传到liunx服务器 /usr/lo ...
- IO—》转换流和缓冲流
转换流 摘要: InputStreamReader和OutputStreamWriter他们分别是FileReader和FileWriter的父类 当只是单纯的读写文件而不改变文件的编码格式时,就分别 ...
- php iamp 接收邮件,收取邮件,获取邮件列表
每次想写的时候吧,提笔忘字.等到再次使用,又得想半天,,,,,好尴尬. 这次一边做一边写. 心得,程序员从菜鸟往老鸟转变的重要一步,学英语,看文档,在此我万分感谢鸟哥,,,,没他php哪有官方的中文注 ...
- 想学Python不知道从哪里开始学?|百度网盘免费下载| 这本入门书了解下
百度网盘免费下载:编程小白的第一本 Python 入门书 提取码:s0pc Python是什么 Python是一种计算机程序设计语言,由吉多·范罗苏姆创造,第一版发布于1991年,可以视之为一种改良的 ...
- Java容器学习之List
List接口继承了Collcetion接口,Collection接口又继承了超级接口Iterable,List是有序列表,实现类有ArrayList.LinkedList.Vector.Stack等. ...
- 从0到1:开启CAN通信学习(一)
1 初识CAN通信 说起CAN通信,可能很多人都比较陌生,但实际上我们却一直在和它打交道.随着家用汽车的普及,我们开车过程中的每次刹车.每次踩油门,甚至每次的开车门.开车窗,其实都是CAN通信的应用 ...
- Webpack 原理浅析
作者: 凹凸曼 - 风魔小次郎 背景 Webpack 迭代到4.x版本后,其源码已经十分庞大,对各种开发场景进行了高度抽象,阅读成本也愈发昂贵.但是为了了解其内部的工作原理,让我们尝试从一个最简单的 ...
- 11、Composite 组合模式 容器与内容的一致性(抽象化) 结构型设计模式
1.Composite模式定义 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这 ...
- 8、Builder 建造者模式 组装复杂的实例 创造型模式
1.什么是Builder模式 定义: 将一个复杂对象的构建与表示相分离,使得同样的构建过程可以创建不同的表示.大白话就是,你不需要知道这个类的内部是什么样的,只用把想使用的参数传进去就可以了,达到了解 ...