cpp11特性(三)
1.auto&&decltype
静态类型:类型检查在编译阶段
动态类型:类型检查在运行阶段
auto声明变量的类型必须由编译器在编译时期推导而得,其优势是在拥有初始化表达式的复杂类型变量声明时简化代码。
decltype以一个普通的表达式为参数,返回该表达式的类型。
用decltype(e)来获取类型时,编译器将依序判断以下四规则:
- 如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么decltype(e)就是e所命名的实体的类型。如果e是一个被重载的函数,则会导致编译时错误。
- 否则,假设e的类型是T,如果e是一个将亡值(xvalue),那么decltype(e)为T&&。
- 否则,假设e的类型是T,如果e是一个左值,则decltype(e)为T&。
- 否则,假设e的类型是T,则decltype(e)为T。
2.追踪返回类型
对返回类型进行类型推导:
template<typename T1, typename T2> //直观的方案
decltype(t1 + t2) Sum(T1 & t1, T2 & t2) {
return t1 + t2;
}
template<typename T1, typename T2> //追踪返回类型的方案
auto Sum(T1 & t1, T2 & t2) -> decltype(t1 + t2) {
return t1 + t2;
}
int func(char *a, int b);
auto func(char *a, int b) -> int ;
把原本的函数返回值移到参数声明之后,而原本的返回值的位置由auto关键字占据。auto占位符和return_type是构成追踪返回类型函数的两个基本元素。
追踪返回类型另一个优势是简化函数的定义,提高代码可读性。
#include<type_traits>
#include<iostream>
using namespace std;
int (*(*pf()) ()) () {
return nullptr;
}
//auto (*)() -> int(*) () 一个返回函数指针的函数(假设为a函数)
//auto pf1() -> auto(*)() -> int(*)() 一个返回a函数的指针的函数
auto pf1() -> auto (*)() -> int(*) { //和上面等价
return nullptr;
}
int main() {
cout << is_same<decltype(pf), decltype(pf1)>::value << endl;
}
追踪返回类型也常用于转发函数中:
#include <iostream>
using namespace std;
double foo(int a) {
return (double)a + 0.1;
}
int foo(double) {
return (int)b;
}
template <class T>
auto Forward(T t) -> decltype(foo(t)) {
return foo(t);
}
int main() {
cout << Forward(2) << endl; //2.1
cout << Forward(0.5) << endl; //0
}

浙公网安备 33010602011771号