C++11关键字:auto 和 decltype

本文详细介绍了C++11中的`auto`和`decltype`两个新特性。`auto`用于自动类型推断,简化了变量声明,但必须初始化。`decltype`则能根据表达式的类型推导出变量的声明类型,常用于需要获取复杂表达式类型的情况。文章通过实例展示了它们的使用方法和常见应用场景,如简化迭代器声明、配合范围for和lambda表达式等。
摘要由CSDN通过智能技术生成

auto

1.简介

在 C++98 中,auto 是一个存储类型的说明符,表明变量是局部自动存储类型,但是在局部域中定义的局部变量默认就是自动存储类型,所以 auto 也就没有实际的用处了。于是,C++11 将 auto 原来的用法改为实现自动类型推断

2.使用

auto 的使用示例如下:

double func()
{
	return 10.4;
}

int main()
{
	int a = 10;
	auto b = a;
	auto c = ']';
	auto d = func();
	
	auto p = &a;
	auto pf = memcpy;  // memcpy是函数指针
	
	vector<int> v;
	auto vv = v;
	
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;
	cout << typeid(vv).name() << endl;
	
	return 0;
}

注:使用语句cout << typeid(变量名).name() << endl;可以打印查看变量的类型。
上面代码的结果是:
控制台

auto 的使用有一个前提:必须对变量进行初始化。因为在编译阶段,编译器需要根据初始化表达式的类型来推导变量实际的类型。因此 auto 并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将 auto 替换为变量实际的类型(比如语句auto e;就无法通过编译,因为使用auto定义变量时没有对其进行初始化)。

auto 还有很多使用细则,这里没有进行展开。

3.常见用法

虽说变量类型声明的简化不是必要的,但是在某些情况下(尤其是在使用模板时),变量类型的声明比较长,不便于程序的书写和阅读,因而在代码上下文便于理解的前提下,往往使用 auto 来简化。

int main()
{
	std::map<std::string, std::string> dict = { { "left", "左边" }, { "insert", "插入" } };
	
	//使用map的迭代器
	//写法1:
	std::map<std::string, std::string>::iterator it = dict.begin();
	//写法2:
	auto it = dict.begin();
	
	/*这两种写法均可,但相对而言明显是写法2更加简洁*/
	
	return 0;
}

auto 还有其它常见的用法,比如和范围for、lambda表达式等进行配合使用。

vector<string> v = { "abc", "def", "ghi", "jkl" };
//范围for
for (auto& e : v)
{
	cout << e << endl;
}
cout << endl;

//lambda表达式
auto test = [](int a, double b)->double {return a * b; };
cout << test(2, 3.14) << endl;

decltype

1.简介

decltype 的作用是根据表达式的实际类型推演出变量的定义类型

decltype 反映其具有获取表达式的“声明类型”(Declared Type)的功能。

2.使用

int main()
{
	const int x = 1;
	decltype(x) y = 4;  // y的类型是const int

	double z = 3.3;
	decltype(x * z) ret;  // ret的类型是double
	decltype(&x) p;  // p的类型是const int*

	return 0;
}

3.常见用法

需要定义一个跟 A 一样类型的对象 B,但 A 的类型不方便写出来或写出来比较复杂,这时可以用 decltype 。

vector<string> func(string s, map<string, string> m)
{
	// ...
}

int main()
{
	//定义函数指针pf
	//写法1:
	vector<string> (*pf)(string, map<string, string>) = func;
	//写法2:
	decltype(&func) pf = func;	
	
	/*pf的类型是函数指针,即:vector<string> (*) (string, map<string, string>)
	两种写法均可,但明显写法2更简洁*/
	

	//定义函数指针vector
	vector<decltype(pf)> v;
	/*vector是类模板,在定义时需要写出参数类型,而decltype可以获取参数类型*/
	/*写成 vector< vector<string> (*) (string, map<string, string>) > v; 也可以,但太过复杂*/

	return 0;
}
std::map<std::string, std::string> dict = { { "left", "左边" }, { "insert", "插入" } };
auto it = dict.begin();  //由于该变量的类型声明比较繁琐,所以用auto简化了
vector<decltype(it)> v;  //但现在需要auto推导对象的类型,这时可用decltype

有些类型由模板参数决定,但难以(甚至不可能)表示该类型,这时可以用 decltype 。

template<class T>
void test(T x)
{
	decltype(x) ret;
	// ...
}
template<class T1, class T2>
void Func(T1 a, T2 b)
{
	decltype(a * b) ret;
	// ...
}

【上期文章】
C++11:列表初始化

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值