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的更多相关文章

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

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

  2. C++ Templates (1.2 模板实参推断 Template Argument Deduction)

    返回完整目录 目录 1.2 模板实参推断 Template Argument Deduction 1.2 模板实参推断 Template Argument Deduction 当调用函数模板(如max ...

  3. C++ 11 Template ... 与Decltype 测试

    #include <iostream> #include "string" using namespace std; template<typename T> ...

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

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

  5. template template parameter

    #include <iostream> using namespace std; template<typename T> class A { }; template<t ...

  6. c++11 template 模板练习

    直接上代码吧 to do // 111111.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> ...

  7. Template template parameter(模板參数) example

    /********************************************************************************* Copyright (C), 19 ...

  8. (转) Overloads and templates

    Overloaded functions In C++, two different functions can have the same name if their parameters are ...

  9. (原) c++ 杂

    Declaration of variables   C++ is a strongly-typed language, and requires every variable to be decla ...

随机推荐

  1. xdebug 一直报错 upstream timed out (110: Connection timed out) while reading response header from upstream

    本地主机(Windows环境192.168.66.1)访问虚拟机(192.168.66.139)里面的搭建的php环境(系统centos6.5版本,php版本是5.5.30 ,xdebug 2.4.0 ...

  2. btrfs的介绍与使用

    源文献:http://www.ibm.com/developerworks/cn/linux/l-cn-btrfs/index.html#ibm-pcon 简单看了一下这篇文章,对其中一些机制的实现还 ...

  3. 如何优雅地使用命令行设置windows文件关联

    如何优雅地使用命令行设置windows文件关联 使用ftype查看帮助 设置关联所需命令有ftype assoc,需要管理员权限.如果忘记使用方法可通过ftype的帮助获取查看方法 C:\WINDOW ...

  4. 2 Python之编程语言介绍及变量

    一: 编程语言介绍 1.机器语言 直接用二进制编程,直接控制硬件,需要掌握硬件的操作细节 优点:执行效率高 缺点:开发效率低 2 汇编语言: 用英文标签取代二级制指令去编写程序,直接控制硬件,需要掌握 ...

  5. SpringMVC的问题No mapping found for HTTP request with URI

    做了一个屏蔽进数据库的操作: Applicaition.xml配置: <?xml version="1.0" encoding="UTF-8"?> ...

  6. Spring框架总结(七)

    Spring代理模式:名词解释: 代理是一种开发的设计模式,用途:提供了对目标对象另外的访问方式,及通过对代理访问目标对象. 优势: 可以在目标对象实现的基础上,增强额外的功能操作,(扩展目标对象的功 ...

  7. 用Word 写csdn blog

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  8. 说说JVM中的操作码

    JVM操作码 加载与存储操作码 load --从局部变量加载值到栈上 ldc --从池中加载常量到栈上 store --把值从栈中移走,存到局部变量中 dup --复制栈顶的值 getField -- ...

  9. 编写高质量代码改善C#程序的157个建议——建议105:使用私有构造函数强化单例

    建议105:使用私有构造函数强化单例 单例指一个类型只生成一个实例对象.单例的一个简单实现如下所示: static void Main(string[] args) { Singleton.Insta ...

  10. 个人写spark小测试

    写脚本生成类似文件 java 代码 封装类 package day0327; import java.util.UUID; public class data { private String ip; ...