C++ decltype的使用

// ConsoleApplicationDecltype.cpp : Defines the entry point for the console application.
//

/*
decltype类型说明符,返回操作数的类型数据,在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值
*/
#include "stdafx.h"
#include "typeinfo"
//#include "stdio.h"
#include "iostream"
using namespace std;
void getSize0();
int getSize1();
string getSize2();
//{
//	cout << "这个函数被调用" << endl;
//	return "test";
//}
//-- 
int add_num2(int &des, int ori){
	cout << "add_num2" << endl;
	return des + ori;
}
void declTypeBasicUsage(){
	int tempA = 2;
	/*dclTempA的类型是int*/
	decltype(tempA) dclTempA = 600;

	cout << typeid(tempA).name() << endl;  //-- 输出int
	cout << typeid(dclTempA).name() << endl; //-- 输出int

	//decltype(getSize0()) decltempb; 编译不通过 函数的返回类型是void
	decltype(getSize1()) decltempc;
	cout << " 输出getSize1函数的返回类型" << typeid(decltempc).name() << endl; //-- 输出函数的返回类型int
	decltype(getSize2()) decltempd;
	cout << " 输出getSize2函数的返回类型" << typeid(decltempd).name() << endl;
	
}
void declTypeComConst(){
	int type = 4;
	switch (type)
	{
	case 1:
	{
		//当使用decltype(var)的形式时,decltype会直接返回变量的类型(包括顶层const和引用)
		int const ci = 0, &cj = ci;
		//x的类型是const int
		decltype(ci) a = 1;
		decltype(cj) b = 2;
		cout << typeid(a).name() << endl;
		cout << typeid(b).name() << endl;

		//expression must be a modifiable
		//表达式必须是可修改的
		//a = 3;  NG
		//b = 4;  NG
		break;
	}
	case 2:
	{
		int  ci = 0, &cj = ci;
		//x的类型是const int
		decltype(ci) a = 1;
		//decltype(cj) b = 2;  非const引用要引用变量
		decltype(cj) b = a;
		cout << typeid(a).name() << endl;
		cout << typeid(b).name() << endl;

		a = 3;
		b = 4;
		break;
	}
	case 3:
	{
		int a[5] = { 1, 2, 3, 4, 5 };
		decltype(a) tempA = { 9,8,7 }; //decltype加数组,不负责把数组转换成对应的指针,所以其结果仍然是个数组
		cout << typeid(tempA).name() << endl;// int [5]
		cout << *tempA << endl; // 9
		cout << *(tempA+1) << endl;// 8
		cout << *(tempA + 4) << endl;// 
	}
	break;
	case 4:
	{
		//-- C++中通过函数的返回值和形参列表,定义了一种名为函数类型的东西。它的主要作用就是定义  函数指针。
		//-- 声明了一个函数类型
		using FuncType = int(int &, int);
		//-- 下面的函数就是上面的类型
		int add_num(int &des, int ori); // 也可以扔到外面  c++

		bool isNormal = true;
		if (isNormal)
		{
			//-- 声明了一个FuncType类型的指针。
			FuncType * pf = NULL;
			//-- 初始化函数指针
			pf = add_num2;

			int a = 2;
			//-- 通过函数指针调用add_to
			pf(a, 2);
		}
		else {
			//-- 直接获得函数的类型
			decltype(add_num) * pf = add_num2;
			cout << typeid(pf).name() << endl;
		}
		break;
	}
	case 5:
	{
		//-- 重要: decltype(expr)的结果根据expr的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。
		int i = 40, *p = &i, &r = i;
		decltype(r+100) a;
		cout << "r+100是一个表达式,算数表达式返回右值,a是一个int类型" << typeid(a).name() << endl;

		decltype(i) b;

		int pp = 55;
		decltype(r) c = pp;

		decltype(p) d = &pp;
		decltype(*p) e = i;   //--e是一个int &;
		//-- 解引用运算符*作用于指针类型,得到了p指向的对象的左值。得到该类型左值的引用(*p = 40很正确),p是指向int的指针,因此decltype(*p)得到的类型是int &。


		//当变量作为表达式时,返回的是该变量的一个左值形式(因为该表达式的结果可以作为赋值语句的左侧的值)。因此,使用decltype理应得到一个该类型的左值引用。
		//但是decltype单独作用于对象,没有使用对象的表达式的属性,而是直接获得了变量的类型。要想获得变量作为表达式的类型,可以加一个括号:
		int k1 = 42;
		decltype(k1) temp1;  //temp1  的类型是int 型
		decltype((k1)) temp2 = k1; //加了括号,变成了表达式, 返回的是k1的左值形式, 因此temp2  的类型是int &型
	}
	break;
	default:
		break;
	}

	getchar();
}
int _tmain(int argc, _TCHAR* argv[])
{
	declTypeBasicUsage();
	declTypeComConst();
	return 0;
}

//decltype是为了解决复杂的类型声明而使用的关键字,称作decltype类型说明符。
//decltype可以作用于变量、表达式及函数名。
//①作用于变量直接得到变量的类型;
//②作用于表达式,结果是左值的表达式得到类型的引用,结果是右值的表达式得到类型;
//③作用于函数名会得到函数类型,不会自动转换成指针。
//decltype不会去真的求解表达式的值。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值