返回完整目录

1.2 模板实参推断 Template Argument Deduction

当调用函数模板(如max())时,模板参数由传入的实参决定。如果传递两个int给参数类型T,C++编译器推断出T的类型为int。

然而,T可能是类型的一部分。比如说,如果声明max()使用常量引用(const reference):

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

并且传递int类型的参数,T同样被推断为int类型,因为函数参数与int const&完全匹配。

类型推断时类型转换

在类型推断中,自动类型转换受到限制:

  • 当声明调用参数(call parameter)为引用类型,甚至一般的转换也不能用于类型推断。两个声明为同一个模板参数(template parameter)T类型的实参必须严格匹配。(Two arguments declared with the same template parameter T must match exactly)。

  • 当声明调用参数为值类型,只有退化(decay)的普通转换才被支持。const或者volatile等限制将被忽略,引用类型转化为被引用的类型,原始数组(raw array)或者函数被转化为对应的指针类型。两个被声明为同一个模板参数T类型的实参,其退化类型必须匹配。

比如:

template <typename T>
T max(T a, T b);
...
int i = 17;
int const c = 42;
max(i, c); //OK: T 被推断为int
max(c, c); //OK: T 被推断为int
int& ir = ;
max(i, ir); //OK: T被推断为int
int arr[4];
max(&i, arr); //OK: T被推断为int*

然而,以下调用将引发错误:

max(4, 7.2);      //Error:T 可能被推断为int或者double
std::string s;
max("hello", s); //Error: T 可能被推断为char const[6]或者std::string

有三种方法来处理此类错误:

  1. 转换实参使得两个参数得以匹配:
max(static_cast<double>(4), 7.2);
  1. 显式指定或者限制T的类型来防止编译器进行类型推断:
max<double>(4, 7.2);
  1. 将两个参数指定为不同的类型。

第1.3节将围绕该方案,第7.2节和第15章将详细讨论类型推断过程中的类型转换规则。

默认实参的类型类型推断 Type Deduction for Default Arguments

默认调用实参(default call arguments)不能用于类型推断,比如:

template <typename T>
void f(T = "");
...
f(1); //OK: T推断为int,因此它将调用f<int>(1)
f(); //Error: 无法推断T类型

为了支持这一情形,必须声明默认模板实参(default argument for the template parameter),这将在1.4节中讨论:

template <typename T = std::string>
void f(T = "");
...
f(); //OK

C++ Templates (1.2 模板实参推断 Template Argument Deduction)的更多相关文章

  1. C++ Templates (1.4 默认模板实参 Default Template Arguments)

    返回完整目录 目录 1.4 默认模板实参 Default Template Arguments 1.4 默认模板实参 Default Template Arguments 可以为模板参数定义默认值,这 ...

  2. 【C++ Primer 第16章】2. 模板实参推断

    模板实参推断:对于函数模板,编译器利用调用中的函数实参来确定模板参数,从函数实参来确定模板参数的过程被称为模板实参推断. 类型转换与模板类型参数 与往常一样,顶层const无论在形参中还是在是实参中, ...

  3. C++学习笔记(4)----模板实参推断

    1. 如图所示代码,模板函数 compare(const T&, const T&) 要求两个参数类型要一样. compare("bye","dad&qu ...

  4. C++ Templates(1.3 多模板参数 Multiple Template Parameters)

    返回完整目录 目录 1.3 多模板参数 Multiple Template Parameters 1.3.1 为返回类型设置模板参数参数 Template Parameters for Return ...

  5. [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断

    条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...

  6. 现代C++之理解模板类型推断(template type deduction)

    理解模板类型推断(template type deduction) 我们往往不能理解一个复杂的系统是如何运作的,但是却知道这个系统能够做什么.C++的模板类型推断便是如此,把参数传递到模板函数往往能让 ...

  7. C++ template —— 实例化和模板实参演绎(四)

    本篇讲解实例化和模板实参演绎-------------------------------------------------------------------------------------- ...

  8. ES - Index Templates 全局index模板

    1.Index Templates 之前我们聊过Dynamic template,它作用范围是特定的Index,如果我们想针对全局Index进行设置该如何操作呢? Index Templates 可以 ...

  9. C++中decltype(*)作为模板实参时的隐藏问题

    在函数模板中使用智能指针时,可能会希望根据指针的类型推导出指针引用的对象类型作为模板参数,于是写出以下代码: shared_ptr<decltype(*objPtr)>(objPtr); ...

随机推荐

  1. vue学习(十) v-for循环普通数组 、对象数组、 迭代数字

    //html <div id="app"> <p v-for="item in list">{{item}}</p> < ...

  2. 给隔壁的妹子讲『一个SQL语句是如何执行的?』

    前言 SQL作为Web开发是永远离开不的一个话题,天天写SQL,可是你知道一个SQL是如何执行的吗? select name from user where id = 1; 上面是一个简单的查询语句, ...

  3. Region Normalization for Image Inpainting, AAAI 2020

    论文:Region Normalization for Image Inpainting, AAAI 2020 代码:https://github.com/geekyutao/RN 图像修复的目的是重 ...

  4. 委托、匿名方法到lambda表达式

    在项目中我们经常会接触lambda表达式,链式操作简洁明了.帮我们省了不少事.面对这么神奇的一个东西,是不是也应该了解了解它的本质呢. 今天我们通过一步一步的演变揭开lambda表达式的本质 一.委托 ...

  5. 彻底解决ssh.invoke_shell() 返回的中文问题

    上一篇:https://www.cnblogs.com/apff/p/9484939.html(python如何实现普通用户登录服务器后切换到root用户再执行命令遇到的错误解决 ) 接上一篇,前两篇 ...

  6. layui常用插件(一) 轮播图

    轮播图 <html lang="en"> <head> <meta charset="UTF-8"> <meta ht ...

  7. jmeter单接口和多接口测试

    @@@@@@@@@@@@@@@ # 路漫漫其修远 最近接触到了多接口串联,接口串联的技术会在其他帖子有说明,其核心技术点就是通过正则表达式和变量来实现接口的关联.目前为止呢笔者用到的地方还只有一个,就 ...

  8. Apple产品价钱分析

  9. Django学习路35_视图使用方法(复制的代码) + 简单总结

    from django.shortcuts import render,redirect from django.http import HttpResponse,JsonResponse from ...

  10. timeit_list操作测试

    ''' timeit库Timer函数 ''' from timeit import Timer def test1(): l = list(range(1000)) def test2(): l = ...