// 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不会去真的求解表达式的值。
C++ decltype的使用
最新推荐文章于 2024-04-06 10:24:20 发布