首页 03-表达式类型推断
文章
取消

03-表达式类型推断

这部分讲解的主要是decltype关键字,这是C++11标准新增的功能,之前笔记记录比较零散,现在都集中于这一章节;

针对变量

这部分主要包括这几部分:

  • 针对指针变量的推断

    1
    2
    3
    4
    5
    6
    
    int x = 3;
    int *p = x;
    decltype(p) q;	// q是一个指向int变量的指针
      
    // 针对函数部分介绍了对函数指针的指向
    // 针对数组部分介绍了对数组的指向
    
  • 针对常规变量的推断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    int x = 42;
    decltype(x) y; // y的类型为 int
      
    int& ref = x;
    decltype(ref) z = y; // z的类型为int&,因为ref是int&类型的引用
      
    int&& right_rex = 3;
    
    // 这样使用是不合法的,因为推导出的r是一个右值引用,right_rex作为一个右值引用,是左值
    decltype(right_rex) r = right_rex;
    decltype(right_rex) r = std::move(right_rex); // 合法修改
    decltype(right_rex) r = 3;  // 合法,3是一个右值,右值引用绑定到右值;
    
  • 针对表达式的推断

    主要是为了强调这么一点:表达式可修改,既然可修改,那就推断为左值;

    1
    2
    
    int x = 42;
    decltype((x)) y;  // y的类型为int&,因为(x)是一个表达式,表达式做左值
    

针对函数

正常情况,针对函数的返回值,一般有如下的推导策略:

1
2
3
4
5
6
7
8
9
int foo();
double bar();

decltype(foo()) result1; // result1的类型为int,根据foo()的返回类型推断
decltype(bar()) result2; // result2的类型为double,根据bar()的返回类型推断

// 而在C++14标准,甚至可以通过auto自动推导
decltype(auto) result1 = foo(); // result1的类型为int,根据foo()的返回类型推断
decltype(auto) result2 = bar(); // result2的类型为double,根据bar()的返回类型推断

如果推导的不是函数,而是函数名呢?

1
decltype(foo) f;

由上可知,foo是一个函数指针,指向一个参数为空,返回类型为int的函数,因此:

推导出f的类型应该是一个指向参数为空,返回类型为int的函数的指针;

针对数组

假如我们知道函数返回的指针将指向哪个数组,就可以使用decltype关键字声明返回类型:

1
2
3
4
5
6
7
8
9
int odd[] = {1, 3, 5, 7, 9};
int even[] = {0, 2, 4, 6, 8};

// 首先decltype(odd)推断的是一个类型,这个类型是一个大小为5的整型数组
// 而arrPtr是一个函数指针,它指向的函数接受一个int型参数,返回的类型是一个大小为5的整型数组
decltype(odd) *arrPtr(int i)
{
    return (i % 2) ? &odd : &even;
}

这就是CPP中表达式类型推断的知识点了;


本文由作者按照 CC BY 4.0 进行授权

02-基础知识

04-const限定符