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 ...
随机推荐
- BUUCTF-Web Comment
dirsearch扫出/.git/目录 遂用航神写的Githacker脚本 https://github.com/wangyihang/githacker 出来的源码并不完整,使用git log ...
- pandas处理excel文件和csv文件
一.csv文件 csv以纯文本形式存储表格数据 pd.read_csv('文件名'),可添加参数engine='python',encoding='gbk' 一般来说,windows系统的默认编码为g ...
- Django学习路26_转换字符串大小写 upper,lower
在 urls 中注册 url(r'getstr',views.getstr) 在 views.py 中添加函数 def getstr(request): string = 'abc' string_2 ...
- 如何部署redis服务
使用工具 redis-64-3.2.100 部署系统 windows server 2012R2 1.下载安装redis-64-3.2.100安装包,下载地址:https://github.com/m ...
- PHP 表单和用户输入讲解
PHP 表单和用户输入 PHP 中的 $_GET 和 $_POST 变量用于检索表单中的信息,比如用户输入. PHP 表单处理 有一点很重要的事情值得注意,当处理 HTML 表单时,PHP 能把来自 ...
- PHP get_html_translation_table() 函数
实例 输出 htmlspecialchars 函数使用的翻译表: <?php高佣联盟 www.cgewang.comprint_r (get_html_translation_table()); ...
- P3270 [JLOI2016]成绩比较 容斥 数论 组合数学 拉格朗日插值
LINK:成绩比较 大体思路不再赘述 这里只说几个我犯错的地方. 拉格朗日插值的时候 明明是n次多项式 我只带了n个值进去 导致一直GG. 拉格朗日插值的时候 由于是从1开始的 所以分母是\((i-1 ...
- CF582D Number of Binominal Coefficients 库默尔定理 数位dp
LINK:Number of Binominal Coefficients 原来难题都长这样.. 水平有限只能推到一半. 设\(f(x)\)表示x中所含p的最大次数.即x质因数分解之后 p的指标. 容 ...
- layui 父页面获取弹窗传递的值 和 父页面传值给子弹窗的方法
1.父页面获取子页面(弹窗)的值: 现在父页面页面加载方法中定义方法,专门用来获取从子页面的值 $(document).ready(function() { //拿到子窗口中传回的数据 functio ...
- Linux搭建Gitlab(Docker版)
1.拉取gitlab的docker镜像 #这里使用gitlab的社区版 docker pull gitlab/gitlab-ce 2.启动gitlab容器实例 docker run -d -p 44 ...