decltype--从表达式推断类型

2019-11-23 22:25:55 浏览数 (1)

前言

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

作用

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

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

用法

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

代码语言:javascript复制
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 &,必须初始化

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

代码语言:javascript复制
int a = 10;
int *p = &a;
decltype(*p) c= a; //c是int &

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

还有双重括号的情况:

代码语言:javascript复制
int a = 10;
decltype((a)) b = a;//b是int &

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

常见应用场景

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

代码语言:javascript复制
//来源:公众号【编程珠玑】 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得到的类型。

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

代码语言:javascript复制
vector<int> vec
typedef decltype(vec.begin()) vecItType;

总结

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

0 人点赞