模板类型的推断

下面的函数f是个模板函数,typename T。下表是,根据调用测的实参,推断出来的T的类型。

请注意下表的红字部分, f(T&& t)看起来是右值引用,但其实它会根据实参的类型,来决定T的类型,如果实参是左值,则它是左值,如果实参是右值,则它是右值。

所以可以看出来,T&可以变成const& ,f(T&& t)也可以变成const&。

f(T t) f(const T t) f(T& t) f(const T& t) f(T&& t) f(const T&& t)
f(1) f<int> f<int> error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int' f<int> f<int> f<int>
int i = 1;
f(i);
f<int> f<int> f<int> f<int> f<int&> error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
int& ri = i;
f(ri);
f<int> f<int> f<int> f<int> f<int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
const int ci = 2;
f(ci);
f<int> f<int> f<const int> f<int> f<const int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
const int& rci = ci;
f(rci);
f<int> f<int> f<const int> f<int> f<const int&> cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’

实验代码

#include <iostream>

template<typename T>
void f1(T t){
t = 99;
} template<typename T>
void f4(const T t){
//t = 99;
} template<typename T>
void f2(T& t){
//t = 99;
} template<typename T>
void f3(const T& t){} template<typename T>
void f5(T&& t){} template<typename T>
void f6(const T&& t){} int main(){
/*
//void f1(T t)
f1(1);//int
int i = 1;
f1(i);//int
int& ri = i;
f1(ri);//int
std::cout << ri << std::endl;
const int ci = 2;
f1(ci);//int
const int& rci = ci;
f1(rci);//int
*/ /*
//void f4(const T t)
f4(1);//int
int i = 1;
f4(i);//int
int& ri = i;
f4(ri);//int
std::cout << ri << std::endl;
const int ci = 2;
f4(ci);//int
const int& rci = ci;
f4(rci);//int
*/ /*
//void f2(T& t)
//f2(1);//error cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
int i = 1;
f2(i);//int
int& ri = i;
f2(ri);//int
const int ci = 2;
f2(ci);//const int
const int& rci = ci;
f2(rci);//const int
*/ /*
//void f3(const T& t)
f3(1);//int
int i = 1;
f3(i);//int
int& ri = i;
f3(ri);//int
const int ci = 2;
f3(ci);//int
const int& rci = ci;
f3(rci);//int
*/ /*
//void f5(T&& t)
f5(1);//int
int i = 1;
f5(i);//int&
int& ri = i;
f5(ri);//int&
std::cout << ri << std::endl;
const int ci = 2;
f5(ci);//const int&
const int& rci = ci;
f5(rci);//const int&
*/ /*
//void f6(const T&& t)
f6(1);//int
int i = 1;
//f6(i);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
int& ri = i;
//f6(ri);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘int’
std::cout << ri << std::endl;
const int ci = 2;
//f6(ci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
const int& rci = ci;
//f6(rci);//error cannot bind rvalue reference of type ‘const int&&’ to lvalue of type ‘const int’
*/ }

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 模板 类型推断的更多相关文章

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

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

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

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

  3. 现代C++之理解auto类型推断

    理解auto类型推断 上一篇帖子中讲述了模板类型推断,我们知道auto的实现原理是基于模板类型推断的,回顾一下模板类型推断: template <typename T> void f(Pa ...

  4. jdk8系列二、jdk8方法引用、重复注解、更好的类型推断、新增注解

    一.方法引用 方法引用使得开发者可以直接引用现存的方法.Java类的构造方法或者实例对象.方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧凑而简洁,没有很多复杂的模板代码. 方法 ...

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

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

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

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

  7. C++ 自动类型推断

    C++语言提供了自动类型推断的机制,用于简化代码书写,这是一种很不错的特性,使用auto和decltype都可以完成自动类型推断的工作,而且都工作在编译期,这表示在运行时不会有任何的性能损耗. 一.a ...

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

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

  9. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

随机推荐

  1. vue学习记录⑤(组件通信-父与子)

    今天我们看一下组件通信. 经过前面几篇文章,我们已经可以构建出完整的单个组件,并利用路由使其串联起来访问了. 但这明显还是不够的.一个页面不可能就是个单组件,一般是由多个组件合成的.正因为如此,组件之 ...

  2. 安卓开发笔记(二十):利用夜神模拟器调试运行Android Studio的apk

    一.首先来到夜神模拟器的安装目录下 如下图所示: 再把这整个文件夹添加到我们的windows环境变量里.然后再把android studio 和夜神模拟器都打开,注意必须同时打开而且不能够把夜神模拟器 ...

  3. 运维DBA要不要学python

    运维DBA要不要学python 我个人认为是:要 现在python在运维数据库的工作中主要用在 1.编写一些运维脚本 2.编写运维管理平台 3.研究互联网大厂的运维脚本/工具并应有 特别是运维开源数据 ...

  4. XMPP协议之消息回执解决方案

    苦恼中寻找方法 在开始做即时通信时就知道了消息回执这个概念,目的是解决通讯消息因为各种原因未送达对方而提供的一种保障机制.产生这个问题的原因主要是网络不稳定.服务器或者客户端一些异常导致没有接收到消息 ...

  5. 暖春许愿季丨i春秋给你送福利

    没有一点点防备 也没有一丝顾虑 就这样出现——暖春许愿季 纳尼?这不是我的歌声里 是i春秋在搞活动 这次准备搞个大的 多大呢 看这里 你许下心愿 我帮你实现 这是一棵神奇的心愿树 是一个畅所欲言之地 ...

  6. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十二║Vue实战:个人博客第一版(axios+router)

    前言 今天正式开始写代码了,之前铺垫了很多了,包括 6 篇基础文章,一篇正式环境搭建,就是为了今天做准备,想温习的小伙伴可以再看看<Vue 基础入门+详细的环境搭建>,内容很多,这里就暂时 ...

  7. 浅谈RabbitMQ Management

    在上一篇博文(centos安装MQ)中,介绍了如何在linux安装rabbitmq,以及安装维护插件,这篇主要介绍介绍rabbitmq_management的UI. vrabbitmq_managem ...

  8. apriori && fpgrowth:频繁模式与关联规则挖掘

    已迁移到我新博客,阅读体验更佳apriori && fpgrowth:频繁模式与关联规则挖掘 详细代码我放在github上:click me 一.实验说明 1.1 任务描述 1.2 数 ...

  9. 一套代码小程序&Web&Native运行的探索07——mpvue简单调研

    前言 接上文:[一套代码小程序&Native&Web阶段总结篇]可以这样阅读Vue源码 最近工作比较忙,加之上个月生了小孩,小情人是各种折腾他爸妈,我们可以使用的独立时间片不多,虽然这 ...

  10. 从PRISM开始学WPF(二)Prism-更新至Prism7.1

    0x1 PRISM? PRISM项目地址:https://github.com/PrismLibrary/Prism 先看下简介: Prism is a framework for building ...