decltype–从表达式推断类型

  • 2019 年 11 月 23 日
  • 笔记

前言

在《不想写表达式的类型?试试auto吧》中介绍了自动类型推导,它需要有初始值,今天再来介绍一个C++11中的特性,decltype。

作用

  • 从表达式类型推断要定义的变量类型
  • 声明返回类型依赖形参类型的函数模板

不过decltype并不会对表达式进行求值。

用法

decltype根据表达式的类型来获取类型。

int a = 1024;  decltype(a) b;//decltype(a),得到int,b为int类型  const char c = 'c';  decltype(c) d = 'd';//d是 const char    int &e = a;  int g = 11;  decltype(e) f = g ;//f是int &,必须初始化

不过下面这种情况需要注意:

int a = 10;  int *p = &a;  decltype(*p) c= a; //c是int &

虽然*p解引用后得到int,但是,c是引用类型,即如果表达式的内容是解引用,将会得到引用类型。

还有双重括号的情况:

int a = 10;  decltype((a)) b = a;//b是int &

如果加了双重括号,它最终也会得到引用类型。

常见应用场景

泛型编程中,如果返回类型与形参类型相关,那么可以使用下面的方式:

//来源:公众号【编程珠玑】 https://www.yanbinghu.com#include<iostream>  template <typename T>  auto add(T x, T y)->decltype(x)  {      return x+y;  }  int main()  {        int a = 10;      int b = 12;      auto c = add(a,b);      std::cout<<c<<std::endl;      return 0;  }

add函数的返回类型与形参类型T有关,因此为了得到返回类型,我们使用auto关键字,但是需要decltype指明是通过表达式x得到的类型。

再比如你想给某个复杂类型取一个别名:

vector<int> vec  typedef decltype(vec.begin()) vecItType;

总结

decltype虽然对于不同场景下得到的类型不同,但是建议在一些不容易产生歧义的方面使用,不应牺牲代码的可读性。