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
}
posted @ 2022-12-19 15:39  无知亦乐  阅读(82)  评论(0)    收藏  举报