一、decltype的意义

  有时我们只想从表达式的类型推断出要定义的变量类型,但是不想用其值进行初始化的时候,C++11新标准引入了decltype类型说明符,它的作用是选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。

二、decltype的用法

  1)基本用法

  int getInt();

  int main()

  {

    int a = 1;

    decltype(a) b;     //b为int类型。

    decltype(getInt()) c; //c为int类型,即使getInt()根本没定义,但程序依旧正常,因为decltype只做分析,并不调用getInt()。

    return 0;

  }

  2)与const结合

  const int a= 0, &b = a;

  decltype(a) c = 0;  //c为const int类型,必须初始化

  decltype(b) d = c;  //d为const int&类型,必须初始化

  decltype(b) e;     //错误,e为const int&类型,必须初始化

  注:从上面的例子可以看出,decltype不会忽略顶层的const,而是保留,这是和auto的一个区别。

  3)与引用结合

  int a = 1,*b = &a,&c = a;

  decltype(a) d = 0;  //d为int类型

  decltype(b) e = &d;  //e为int*类型

  decltype(*b) f = d;    //f为int&类型(表达式内容为解引用操作,可以这么理解,b是指针,而对*b的操作会影响到d的值,和引用功能相同)

  decltype(c) g = d;  //g为int&类型

  decltype(c+1) h = d;   //h为int类型,c的类型为int&,但是c+1表达式计算之后返回的类型是int,因此h的类型是int

  std::cout << d << std::endl;  //输出0(输出d的值)

  std::cout << ++(*e) <<std::endl;//输出1(d先自加1变为1,再输出)

  std::cout << ++f  <<std::endl;    //输出2(d先自加1变成2,再输出)

  std::cout << ++g << std::endl;   //输出3(d先自加1变成3,再输出)

  std::cout << ++h << std::end;    //输出1(h先自加1变成1,再输出)

  4)与括号

  int a = 1;

  decltype((a)) b = 2;//b为int&类型,必须初始化

  注:如果一个表达式的类型不是引用,但是我们需要推断该类型的引用,那么可以加上一对括号,就变成了引用类型。

  5)与函数返回类型

  template <typename T1,typename T2>  

  auto Func(T1 t1,T2 t2> -> decltype(t1 * t2)

  {

    return t1 * t2;

  }

  6)总结

  decltype和auto都可以用来推断类型,但二者有几处明显的差异:

  1、auto忽略顶层const、decltype保留顶层const。

  2、对引用操作,auto推断原有类型;decltype推断出引用。

  3、对解引用的操作,auto推断出原有类型;decltype推断出引用。

  4、auto推断时会实际执行,decltype不会执行,只做分析。

C++11常用特性介绍——decltype关键字的更多相关文章

  1. C++11常用特性介绍——nullptr关键字及用法

    一.nullptr关键字及用法 1)NULL的二义性 void func(int) {} void func(int*) {} 当函数调用func(NULL)时会执行哪个函数呢? 先看C++对NULL ...

  2. C++11常用特性介绍——auto类型修饰符

    1.C++11常用特性介绍 从本篇开始介绍C++11常用特性,大致分:关键字及新语法.STL容器.多线程.智能指针内存管理,最后讲一下std::bind和std::function 二.关键字和新语法 ...

  3. C++98常用特性介绍——mutable关键字

    讲mutable前,先讲一下const函数,讲const函数前,先讲一下函数前后加const的区别 一.C++函数前后加const的区别 1)函数前加const:普通函数或非静态成员函数前均可加con ...

  4. C++11常用特性介绍——array容器

    std::array是具有固定大小的数组,支持快速随机访问,不能添加或删除元素,定义于头文件<array>中. 一.概要 array是C++11新引入的容器类型,与内置数组相比,array ...

  5. C++11常用特性介绍——列表初始化

    一.列表初始化 1)C++11以前,定义初始化的几种不同形式,如下: int data = 0;   //赋值初始化 int data = {0};   //花括号初始化 int data(0); / ...

  6. C++11常用特性介绍——Lambda表达式

    一.C++11采用配对的方括号[]来创建一个匿名函数并执行,如: #include <iostream> int main() { auto func = []{ std::cout &l ...

  7. C++11常用特性介绍——左值引用、右值引用

    一.左值.右值 1)左值:可以放在赋值号左侧.可以被赋值的值:左值必须要在内存中有实体. 2)右值:必须放在赋值号右侧.取出值赋值给其它变量:右值可以在内存中也可以在CPU寄存器中. 二.引用 引用是 ...

  8. C++11常用特性介绍——constexpr变量

    一.constexpr变量 1)将变量声明为constexpr类型以便由编译器来验证变量的值是否为一个常量表达式,声明为constexpr的变量一定是一个常量,而且必须用常量表达式来初始化,如: in ...

  9. C++11常用特性介绍——for循环新用法

    一.for循环新用法——基于范围的for循环 for(元素类型 元素对象 : 容器对象) { //遍历 } 1)遍历字符串 std::string str = "hello world&qu ...

随机推荐

  1. 【转载】JDBC操作LOB字段

    转自:http://www.cnblogs.com/tengtao93/p/4984689.html 1.LOB(Large Objects)大对象,是用来存储大量的二进制和文本数据的一种数据类型(一 ...

  2. python开发基础02-字符串操作方法练习题

    1.执行 Python 脚本的两种方式 python解释器 py文件  #!/usr/bin/env python 进入python解释器,便捷命令并执行 pycharm或其他pythonIDE sh ...

  3. Bugku-CTF之本地包含( 60)

    Day36  

  4. hackinglab 冒充登录用户

    首先进入网页会发现 直接用bp进行抓包然后会发现一个字母是Login这个是登录的意思发现这个字母等于0我们大胆的猜测一下这个字母等于0代表的是没有登陆而如果这个字母是1或者是2的时候就是登录了然后我们 ...

  5. ISR吞吐性能问题

    ISR大致可以分几类: Cisco 860.880.890 ISR1800 (fixed).1800 (modular).2800.3800 Series ISR1900.2900.3800.3900 ...

  6. Javascript模块化编程之CommonJS,AMD,CMD,UMD模块加载规范详解

    JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?     模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问 题进行系 ...

  7. cordova的安装与配置

    1.安装nodejs(自动包含npm) 2.在命令行中通过npm语句npm install -g cordova 安装cordova(如果提示网络连接失败,需要设置网络代理,搭理网址:npm conf ...

  8. 每天进步一点点------SOPC的Avalon-MM IP核(二) AVALON总线的IP核定制

    简介 NIOS II是一个建立在FPGA上的嵌入式软核处理器,除了可以根据需要任意添加已经提供的外设外,用户还可以通过定制用户逻辑外设和定制用户指令来实现各种应用要求.这节我们就来研究如何定制基于Av ...

  9. keil(MDK)错误记录

    1.a parameter list without types is only allowed in a function definition(没有类型的参数列表只允许在函数定义中使用) 2.Er ...

  10. C:防止头文件重复包含

    当一个项目比较大时,往往都是分文件,这时候有可能不小心把同一个头文件 include 多次,或者头文件嵌套包含. 方法一: #ifndef __SOMEFILE_H__ #define __SOMEF ...