实例代码


// 详解decltype含义,decltype主要用途#include <iostream>
#include <functional>
#include <vector>
#include <map>using namespace std;class CT{public:int i;int j;};int testf(){return 10;
}const int &&myfunctest(void) {return 0;
}template<typename T>
class CT1{public:typename T::iterator iter; //迭代器类型void getbegin(T& tmpc){// ...iter = tmpc.begin();}
};template<typename T>
class CT2{public://typename T::iterator iter; //迭代器类型decltype(T().begin) iter;  // const std::vector<int>() 表示 生成该类型的临时对象。调用了这个临时对象的begin()void getbegin(T& tmpc){// ...iter = tmpc.begin();}
};class A{public:A(){cout << "执行A构造函数" << endl;}~A(){cout << "执行A析构函数" << endl;}int func() const{cout << "执行A的func函数" << endl;return 0;}int m_i;
};auto add(int a, int b)->decltype(a + b) {return a + b;
};int tf(int &i){return i;
}double tf(double &d){return d;
}template<typename T>
auto FuncTmp(T &tv)->decltype(tf(tv)){ // auto 在这里没有自动类型推断的含义,这里它只是返回类型后置语法的组成部分。return tf(tv);
}template<typename T>
T& mydouble(T &v1){v1 *= 2;return v1;
}template<typename T>
decltype(auto) mydouble1(T &v1){ // 把auto理解成要推导的类型。推导过程我们采用decltypev1 *= 2;return v1;
}decltype(auto) tf1(){int i = 1;return i;
}decltype(auto) tf2(){int i = 1;return (i);  // 加了括号导致返回 int& , 但是要用这个返回的东西,则就会导致不可预料的后果
}int main(int argc, const char * argv[]) {//一: decltype 含义和举例// decltype:用于推导类型,对于一个给定的变量名或者表达式,decltype能够告诉你该名字或者表达式的类型。// auto a = 10; //我们并不想用表达式的值初始化这个变量// C++ 11, decltype(说明符) :主要作用:返回操作数的数据类型。// decltype 特点://(a): decltype 的自动类型推断会发生在编译器(和auto一样)//(b): decltype 不会真正计算表达式的值//(1.1) decltype 后的圆括号中是个变量const int i = 0;const int &iy = i;auto j1 = i;  // j1 = int  //传值方式推断:引用属性、const属性都会被抛弃的, j1 = intdecltype(i) j2 = 15;  // j2 = const int。如果decltype中是个变量,则变量的const属性会返回。decltype(iy) j3 = j2; // j3 = const int & 。如果decltype中是个变量,变量的const属性,以及引用属性&都会被返回。// decltype 很循规蹈矩,有啥返回啥。decltype(CT::i) a;      // a = int; 类访问表达式CT tmpct;decltype(tmpct) tmpct2; // tmpct2 = CTdecltype(tmpct2.i) mv = 5;// int  类访问表达式int x = 1, y = 2;auto &&z = x; // x左值,auto = int& , z = int & 。万能引用decltype(z) && h = y; // int &h = y; 这里用到了引用折叠规则(折叠成了左值)。//(1.2) decltype 后的圆括号中非变量(是表达式)// decltype 会返回表达式的结果对应的类型。decltype(8) kkk = 5; // kkk intint ii = 0;int *pii = &ii;int &iiy = ii;decltype(iiy + 1) jj;  // j = int ,因为iiy + 1得到一个整形表达式decltype(pii) k;  // k = int* ; pii是个变量。*pii = 4;decltype(*pii) k2 = ii; // k2 = int&;// *pii是指针pii所指向的对象,而且能够给这个对象赋值,所以*pii是个左值// *pii是个表达式, 不是变量,因为它有*号// 如果表达式结果能够作为赋值语句左边的值,那decltype 后返回的就是个引用。// 所以这种情况要专门记:// decltype 后边是个非变量的表达式,并且表示能够作为等号左边内容,返回的就是一个类似int &decltype(ii) k3; // k3 = int ,ii 只是个变量decltype((i)) iy3 = ii; // 如果在变量名外w额外增加了一层或者多层括号(),那么编译器就会把这个变量当成一个表达式// 又因为变量可以作为等号左边的内容;最终iy3 = int &(ii) = 6;//结论 decltype((变量)) 的结果永远都是引用//(1.3) decltype 后的圆括号中是函数decltype(testf()) tmpv = 14; // tmpv的类型就是函数testf()的返回类型int。// 这里编译器没有去调用过函数testf().只是使用函数testf()的返回值类型作为tmpv的类型decltype(testf) tmpv2; // tmpv2 = int(void), 这个有返回类型,有参数类型,代表一种可调用对象。// 标准库function用法,类模板:function<decltype(testf)> ftmp = testf; //声明了一个function(函数)类型,用来代表一个可调用对象。// 它所代表的可调用对象是一个int(void);cout << ftmp() << endl; //10decltype(myfunctest()) myy = 0;  // myy = const int &&//二: decltype 主要用途//(2.1) 应付可变类型,一般decltype主要用途还是应用于模板编程中。using conttype = std::vector<int>; //定义类型别名conttype myarr = { 10, 30, 40 };  //定义该类型变量,现在myarr是个容器CT1<conttype> ct1;ct1.getbegin(myarr);//如果对于const 常量容器,上面的处理就会报错,//using conttype1 = const std::vector<int>; //定义类型别名//conttype1 myarr = {10,30,40};  //定义该类型变量,现在myarr是个容器//CT1<conttype1> ct1;//ct1.getbegin(myarr);//在C++98时代,这里要用模板偏特化来解决, 但c++ 11之后我们可以用 decltype 很容易解决这种问题//如上:class CT2 模板类的编写A().func(); // 生成了一个临时对象,调用临时对象的func()函数// 执行了A构造,A的func() ,A的析构函数//(const A()).func(); //本执行结果和上面一样decltype(A().func()) aaa; // aaa = int ,根本没构造过A类对象; 也没有调用过func()//(2.2) 通过变量表达式抽取变量类型vector<int> ac;ac.push_back(1);ac.push_back(2);vector<int>::size_type mysize = ac.size();cout << mysize << endl; // 2decltype(ac)::size_type mysize2 = mysize; //抽取ac的类型 vector<int> ,所以这行相当于 vector<int>::size_type mysize2 = mysize;cout << mysize2 << endl; // 2typedef decltype(sizeof(0)) size_t; // sizeof(0) 等价于 sizeof(int)size_t abc;abc = 1;//(2.3) auto 结合decltype构成返回类型后置语法//如上面的 add 函数int i11 = 19;cout << FuncTmp(i11) << endl; // 19double d = 28.1f;cout << FuncTmp(d) << endl; // 28.1//(2.4) decltype(auto) 用法  c++14才支持的语法//a). 用于函数返回类型int a11 = 100;mydouble(a11) = 20; // int &cout << a11 << endl; // a11 = 20;decltype(mydouble1(a11)) b11 = a; // b = int&//b). 用于变量声明中int xx = 1;const int &yy = 1;auto zz = yy; // z = int , const 和引用 都没了decltype(auto) zz2 = yy; // zz2 = const inyyt &;// auto 丢掉的东西(const,引用),能够通过decltype(auto) 捡回来。//c). 再说(x)int iii = 10;decltype((iii)) iiiy3 = iii; // iiiy = int &;decltype(tf1()) testa = 4; // intint aaaa = 1;decltype(tf2()) testb = aaaa; // testb = int &tf2() = 12;// 语法上没问题, 但是真这么做,会发生未预料行为。//三:总结system("pause");return 0;
}

C++语法学习笔记二十九: 详解decltype含义,decltype主要用途相关推荐

  1. opencv学习笔记二十九:SIFT特征点检测与匹配

    SIFT(Scale-invariant feature transform)是一种检测局部特征的算法,该算法通过求一幅图中的特征点(interest points,or corner points) ...

  2. Mr.J-- jQuery学习笔记(二十九)--属性操作方法(获取属性判断)

    获取 attr() <span class="span1" name="it666"></span> <span class=&q ...

  3. Linux学习笔记二十九——http服务

    基础概念: HTTP:Hyper Text Transfer Protocol 超文本传输协议 versions: HTTP/0.9:只接收GET一种请求方法,只支持纯文本 HTTP/1.0:支持PU ...

  4. python数据挖掘学习笔记】十九.鸢尾花数据集可视化、线性回归、决策树花样分析

    #2018-04-05 16:57:26 April Thursday the 14 week, the 095 day SZ SSMR python数据挖掘学习笔记]十九.鸢尾花数据集可视化.线性回 ...

  5. 嵌入式系统设计师学习笔记二十八:嵌入式程序设计③——高级程序设计语言

    嵌入式系统设计师学习笔记二十八:嵌入式程序设计③--高级程序设计语言 解释程序和编译程序 编译器的工作阶段示意图 语法错误:非法字符,关键字或标识符拼写错误 语法错误:语法结构出错,if--endif ...

  6. Python学习笔记(十九)面向对象 - 继承

    Python学习笔记(十九)面向对象 - 继承 一.继承的概念 # 继承:子类继承父类的所有方法和属性# 1. 子类 class A(object):def __init__(self):self.n ...

  7. Mr.J-- jQuery学习笔记(二十八)--DOM操作方法(添加方法总结)

    Table of Contents appendTo appendTo(source, target) 源代码 append prependTo ​ ​ ​ ​ prependTo源码 prepend ...

  8. JavaScript学习(二十九)—JS常用的事件

    JavaScript学习(二十九)-JS常用的事件 一.页面相关事件 onload事件:当页面中所有的标签都加载完成后厨房该事件,格式:window.onload <body><sc ...

  9. uniapp 学习笔记二十二 购物车页面结构搭建

    uniapp 学习笔记二十二 购物车页面结构搭建 cart.vue <template><view><view class="flex padding" ...

最新文章

  1. Linux环境变量说明与配置
  2. 实现数据“一键脱敏”,Sharding Sphere帮你搞定
  3. 【转发】关于Java性能的9个谬论
  4. NetDevOps — YANG 协议
  5. 5、mybatis中的映射器
  6. SharePoint2007 配置MOSS基于AD的Forms验证
  7. React组件生命周期-正确执行运行阶段的函数
  8. AndroidManifest.xml文件的作用和简单使用
  9. 为什么将iostream :: eof放在循环条件(即`while(!stream.eof())`)内?
  10. 【网络编程】Socket网络编程基础
  11. 学海无涯!马士兵的Java教程
  12. 第35讲:Xposed+模拟器的详细使用
  13. 钛灵科技入驻中国视界,共筑人工智能视觉产业新高地
  14. 优秀网页翻译:高精度 10MHz GPS 驯服钟 (GPSDO) - Part 4
  15. 教你绘制一张精美的思维导图
  16. c9计算机专业考研哪个容易,22考研:C9上岸学姐告诉你!考研到底需要准备多久?...
  17. 芯科EFRBG22C112 empty工程创建
  18. 第二十一天Python之进程
  19. C++:后缀增量和减量运算符:++ 和 --
  20. Inno setup 删除指定文件

热门文章

  1. 萌新记录自己刷过的题
  2. STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯
  3. C++基础 Data类的实现
  4. 在html中调用QQ,MSN,旺旺,Skype,Email的方法
  5. 英文投稿时图片的处理方法
  6. 1111111111111111111111111111
  7. codeblocks下如何修改新建文件的默认代码?
  8. 乐博机器人Arduino周五班级,入门课程,碰撞开关控制灯闪烁
  9. 南昌专门学计算机的技校,2019南昌技校计算机专业都学什么有哪些专业-江西技校都有什么专...
  10. c语言实验教学软件,C语言实验教学法综述