函数的默认模板参数

你可以为模板参数定义默认值,它们被称作 default template arguments(默认模板参数)。

它们甚至可以指向前一个模板参数。

1. 可以直接使用 operator?:

#include <iostream>

// 引入这个玩意儿生成共同类型
#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;
}

int main() {
    using namespace std;
    // 这个 double 专门为了 RT 而指定的, T1 和 T2 都可以通过调用参数推导出来
    auto a = ::max(2, 3.2);
    auto b = ::max(5, 1.2);
    cout << "max(2, 3.2) = " << a << endl;
    cout << "max(5, 1.2) = " << b << endl;
    return 0;
}

这里要求我们能调用传入类型的默认构造函数。

2. 用 std::common_type<> 追踪返回的默认值

#include <iostream>

// 引入这个玩意儿生成共同类型
#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;
}

int main() {
    using namespace std;
    // 这个 double 专门为了 RT 而指定的, T1 和 T2 都可以通过调用参数推导出来
    auto a = ::max(2, 3.2);
    auto b = ::max(5, 1.2);
    cout << "max(2, 3.2) = " << a << endl;
    cout << "max(5, 1.2) = " << b << endl;
    return 0;
}

由于 std::common_type<> decays,所以这里的返回值不能是引用。

但是这两种方法还是避免不了要显式指定参数列表的情况。

这里可以用一个其主要作用的默认模板参数。

#include <iostream>

// 引入这个玩意儿生成共同类型
#include <type_traits>

template<typename RT = long, typename T1, typename T2>
RT max(T1 a, T2 b) {
    return b < a ? a : b;
}

int main() {
    using namespace std;
    // 这个 double 专门为了 RT 而指定的, T1 和 T2 都可以通过调用参数推导出来
    int a = ::max(2, 3.2);      // 返回 int 类型
    long b = ::max(5, 1.2);     // 返回 long 类型
    cout << "max(2, 3.2) = " << a << endl;
    cout << "max(5, 1.2) = " << b << endl;
    return 0;
}

这里我们还是需要依赖于之前模板参数的默认了类型,所以最简单的方法还是让编译器自动推导返回类型。

也就是用 auto。

C++ 函数模板默认的模板参数的更多相关文章

  1. C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化

    一.内联函数     常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...

  2. [Reprint] C++函数模板与类模板实例解析

    这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下   本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...

  3. C++学习之函数模板与类模板

    泛型编程(Generic Programming)是一种编程范式,通过将类型参数化来实现在同一份代码上操作多种数据类型,泛型是一般化并可重复使用的意思.泛型编程最初诞生于C++中,目的是为了实现C++ ...

  4. C++进阶-1-模板基础(函数模板、类模板)

    C++进阶 模板 1.1 函数模板 1 #include<iostream> 2 using namespace std; 3 4 // 模板 5 6 // 模板的简单实例 7 // 要求 ...

  5. C++学习35 模板中的函数式参数

    C++对模板类的支持比较灵活,模板类的参数中除了可以有类型参数,还可以有普通参数.例如: template<typename T, int N> class Demo{ }; N 是一个普 ...

  6. C++_进阶之函数模板_类模板

     C++_进阶之函数模板_类模板 第一部分 前言 c++提供了函数模板(function template.)所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来 ...

  7. C++复习:函数模板和类模板

    前言 C++提供了函数模板(function template).所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表.这个通用函数就称为函数模板.凡是函数体 ...

  8. C++17尝鲜:类模板中的模板参数自动推导

    模板参数自动推导 在C++17之前,类模板构造器的模板参数是不能像函数模板的模板参数那样被自动推导的,比如我们无法写 std::pair a{1, "a"s}; // C++17 ...

  9. 【校招面试 之 C/C++】第2题 函数模板、类模板、特化、偏特化

    1.C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样 ...

随机推荐

  1. BZOJ.5251.[八省联考2018]劈配mentor(最大流)

    BZOJ 洛谷 对于每个人,每次枚举一个志愿看是否能增广即可. 对于第二问,可以保留第一问中\(n\)次增广前后的\(n\)张图,二分,在对应图上看是否能增广即可. 貌似匈牙利的某种写法比网络流优多了 ...

  2. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  3. 3ds max学习笔记(九)-- 实例操作(路径阵列)

    栅栏 路径阵列也叫间隔工具,将选择的物体沿指定的路径进行复制.实现物体在路径上的饿均匀分布. 选择需要分布的物体对象,在视图中绘制二维图形做为路径线条. 1.选择线条,制作路径 2.选择需要分布的物体 ...

  4. 3ds max学习笔记(三)--视点显示控制

    显示模式:1.模型一般是以实体方式显示的,若想看线框方式,摁F3:返回实体,摁F3:2.实体加线框模式显示,摁F4:返回,摁F4:3.透明效果:ALT+X,透明显示,之后F4,显示线框:程序内的其他显 ...

  5. redis:aof恢复与rdb服务器间迁移

    1. aof恢复与rdb服务器间迁移: 1.1. Aof恢复: 如果不小心执行了flushdb或flushall了怎么办? (1)立马执行命令:shutdown nosave 关闭服务器,为了防止其他 ...

  6. 一步步完成Maven+SpringMVC+SpringFox+Swagger整合示例

    本文给出一个整合Maven+SpringMVC+SpringFOX+Swagger的示例,并且一步步给出完成步骤. 本人在做实例时发现 http://blog.csdn.net/zth1002/art ...

  7. js动态时间(转)

    html代码 <span id="timeShow" show_cur_times()></span> js代码 $(function(){ //设置1秒调 ...

  8. Hibernate(1)基本知识

    hibernate初步 1.概述 ①hibernate是java应用和关系数据库之间的桥梁,是一个开源的对象关系映射框架,可用来把对象模型表示的java对象 映射到关系型数据库表中去. ②hibern ...

  9. 前端工程化系列[05] Yeoman脚手架使用入门

    Yeoman是一款流行的前端的脚手架工具. 脚手架工具可以用来快速的自动生成项目的必要文件和基础文件结构.Yeoman使用的内建命令为yo,同时它自己也是一个包管理工具和自动化任务工具,它基于特定的模 ...

  10. 处理程序“AllowAccessJavaScripts”在其模块列表中有一个错误模块“ManagedPipelineHandler”

    处理程序“AllowAccessJavaScripts”在其模块列表中有一个错误模块“ManagedPipelineHandler” 执行命令"cd C:\Windows\Microsoft ...