C++11 template parameter deduction
C++11 引入了右值引用的概念,由此在引出 an rvalue reference to a cv-unqualified template parameter. 在template function 推导中,我们需要推导出template parameter.
那么template function的参数推导,有几种形式呢?答案是三种(暂时不考虑加const T的情况), 注意这跟class template不一样,function template 没有偏特化的概念(partial specialization)
template<typename T> template<typename T> template<typename T>
void func(T t) void func(T& t) void func(T&& t)
第一种情况最简单,参数推导也容易。形参和template 参数的类型完全一样,这是因为T t拷贝外部形参。理由很简单,既然是拷贝,那么实参的const属性跟就形参无关。引用更加无关
int x = 27; // as before
const int cx = x; // as before
const int& rx = x; // as before f(x);
func(x) // T's and param's types are both int
func(cx) // T's and param's types are again both int;
func(rx) // T's and param's types are still both int
func(25) // 25 is rvalue
第二种情况呢,首先我们分析一下第二种情况,T&t,a lvalue reference to a cv-unqualified template paramter. 这种情况跟我们通常的fun(int &)类似,只是需要模板推导T.所以实参的const属性会传导到T.
int x = 27; // x is an int
const int cx = x; // cx is a const int
const int& rx = x; // rx is a reference to x as a const int
the deduced types for param and T in various calls are as follows:
f(x); // T is int, param's type is int&
f(cx); // T is const int, // param's type is const int&
f(rx); // T is const int, // param's type is const int&
注意template <class T> void func<T& t)不能接受右值.
那么在C++11之前,如果想template function 的parameter 接受rvalue,怎么办呢?跟普通函数一样,使用const T&
template<class T >
void func(const T& t)
左值右值能接收,编译通过。此时如果类型推导T呢?这种情况就退化成第一种情况。
c++11 中引入了右值引用的概念,那么在template function中是否也有类似的概念呢?答案是肯定的,但是跟普通的右值引用不同,template中引入的是forwarding reference, 其定义是an rvalue reference to a cv-unqualified template parameter.
但是根据template parameter T类型的不同, T&&可能是左值,也可能是右值。这就是Scott Meyers的通用引用。标准里叫做forwarding reference.
你可能会说,为什么要引入这个概念呢?不是有const T&去接收右值吗?答案是为了完美转发,如果用const T&t ,那么t永远都是左值引用。如果实参是什么。 而通用引用可以区分出右值和右值。那么如果推导呢?
template<class T>
void func(T&&t)
int x = 27; // as before
constint cx = x; // as before
const int& rx = x; // as before
f(x); // x is lvalue, so T is int&, // param's type is also int&
f(cx); // cx is lvalue, so T is const int&, // param's type is also const int&
f(rx); // rx is lvalue, so T is const int&, // param's type is also const int&
f(27); // 27 is rvalue, so T is int, // param's type is therefore int&&
由此可知,const的属性保留, 当实参是右值的时候,T就是int。我们可以这么理解,因为T&&t是模板参数的右值引用,如果实参是左值,那么T必须加&,通过引用折叠T&& &->T&才能不报错.如果是右值,那么就无需这一步转换
那么什么是引用折叠呢?根本原因就是C++不支持引用的引用这个概念
T&& &->T&
T& &-> T&
T&& &&-> T&&
T& &&->T&
C++11 template parameter deduction的更多相关文章
- 现代C++之理解模板类型推断(template type deduction)
理解模板类型推断(template type deduction) 我们往往不能理解一个复杂的系统是如何运作的,但是却知道这个系统能够做什么.C++的模板类型推断便是如此,把参数传递到模板函数往往能让 ...
- C++ Templates (1.2 模板实参推断 Template Argument Deduction)
返回完整目录 目录 1.2 模板实参推断 Template Argument Deduction 1.2 模板实参推断 Template Argument Deduction 当调用函数模板(如max ...
- C++ 11 Template ... 与Decltype 测试
#include <iostream> #include "string" using namespace std; template<typename T> ...
- [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断
条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...
- template template parameter
#include <iostream> using namespace std; template<typename T> class A { }; template<t ...
- c++11 template 模板练习
直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...
- Template template parameter(模板參数) example
/********************************************************************************* Copyright (C), 19 ...
- (转) Overloads and templates
Overloaded functions In C++, two different functions can have the same name if their parameters are ...
- (原) c++ 杂
Declaration of variables C++ is a strongly-typed language, and requires every variable to be decla ...
随机推荐
- 相机IMU融合四部曲(一):D-LG-EKF详细解读
相机IMU融合四部曲(一):D-LG-EKF详细解读 极品巧克力 前言 前两篇文章<Google Cardbord的九轴融合算法>,<Madgwick算法详细解读>,讨论的都是 ...
- 区分 hdfs hbase hive hbase适用场景
区分 hdfs hbase hive hbase适用场景 收藏 八戒_o 发表于 11个月前 阅读 308 收藏 1 点赞 0 评论 0 摘要: hdfs hbase hive hbase适用场景 H ...
- mysql user表 权限字段详解
Select_priv.确定用户是否可以通过SELECT命令选择数据. Insert_priv.确定用户是否可以通过INSERT命令插入数据. Update_priv.确定用户是否可以通过UPDATE ...
- Redis与Java的链接Jedis(二)
就像jdbc跟java链接数据库一样 redis跟java链接最好的工具就是Jedis 相关资源下载:https://github.com/xetorthio/jedis 正常建立java项目, 导入 ...
- C++11之Lambda特性探析
目录 目录 1 1. 什么是Lambda? 1 2. 语法格式 1 2.1. 语法格式 1 2.2. 最简定义 2 3. 应用示例 2 4. capture列表 3 4.1. 基本形式 3 4.2. ...
- Android view状态保存
为什么我们需要保存View的状态? 这个问题问的好!我坚信移动应用应该帮助你解决问题,而不是制造问题. 想象一下一个非常复杂的设置页面: 这并不是从一个移动应用的截图(这不是典型的win32程序吗.. ...
- CentOS 下 zookeeper 安装
搭建zookeeper需要几个条件 a. 配置Java环境 c. centos d. 下载 xshell5 (下载它只是为了更方便的使用linux) 一.新建一个myapp目录: 二.下载 ...
- ubuntu eclipse 集成pyDev
Eclipse help 选择安装新软件 添加一个pydev 名字随意.地址是 http://pydev.org/updates. 下面的列表会出现很多PyDev For Eclipse 选择版本最高 ...
- Verilog MIPS32 CPU(一)-- PC寄存器
Verilog MIPS32 CPU(一)-- PC寄存器 Verilog MIPS32 CPU(二)-- Regfiles Verilog MIPS32 CPU(三)-- ALU Verilog M ...
- Mathcad操作tips:算式输入、变量定义与计算
算式输入 1. 数字与符号相乘,输入时不必手动输入乘号(“*”). 2. 以下有助于算式的可视化:a. 使用Math工具栏输入,并合理使用tab键:b. 合理使用空格键. 3. 输入开根号时,可用快捷 ...