C++ 11 auto & decltype 关键字 返回值后置语法

auto

C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型。

注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。使用 auto 类型推导的变量必须马上初始化,这个很容易理解,因为 auto并非如 int 一样的真正的类型声明。

推导原则

  1.当赋值运算符右边的表达式是一个引用类型时,auto 会把引用抛弃,直接推导出它的原始类型。

  2.如果表达式的类型不是指针或者引用,auto 会把 cv(const,volatile) 限定符直接抛弃,推导成 non-const 或者 non-volatile 类型。

  3.如果表达式的类型是指针或者引用,auto 将保留 cv 限定符。

auto的限制

1)  auto 不能在函数的参数中使用。

这个应该很容易理解,我们在定义函数的时候只是对参数进行了声明,指明了参数的类型,但并没有给它赋值,只有在实际调用函数的时候才会给参数赋值;而 auto 要求必须对变量进行初始化,所以这是矛盾的。

2)  auto 不能作用于类的非静态成员变量(也就是没有 static 关键字修饰的成员变量)中。

3)  auto 关键字不能定义数组。

4)  auto 不能作用于模板参数。

auto的应用

  1. 使用 auto 定义迭代器
  2. auto 用于泛型编程

decltype

decltype 是“declare type”的缩写,译为“声明类型”。

既然已经有了 auto 关键字,为什么还需要 decltype 关键字呢?因为 auto 并不适用于所有的自动类型推导场景,在某些特殊情况下 auto 用起来非常不方便,甚至压根无法使用,所以 decltype 关键字也被引入到 C++11 中。

auto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:

auto varname = value;

decltype(exp) varname = value;

其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。

auto 根据赋值运算符右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟赋值运算符右边的 value 没有关系。

另外,auto 要求变量必须初始化,而 decltype 不要求。这很容易理解,auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。decltype 可以写成下面的形式:

decltype(exp) varname;

exp 注意事项

原则上讲,exp 就是一个普通的表达式,它可以是任意复杂的形式,但是我们必须要保证 exp 的结果是有类型的,不能是 void;例如,当 exp 调用一个返回值类型为 void 的函数时,exp 的结果也是 void 类型,此时就会导致编译错误。

decltype 推导规则

  1.如果 exp 是一个不被括号( )包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,那么 decltype(exp) 的类型就和 exp 一致,这是最普遍最常见的情况。

  2.如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。需要注意的是,exp 中调用函数时需要带上括号和参数,但这仅仅是形式,并不会真的去执行函数代码。

  3.如果 exp 是一个左值,或者被括号( )包围,那么 decltype(exp) 的类型就是 exp 的引用;假设 exp 的类型为 T,那么 decltype(exp) 的类型就是 T&。

 

 

返回值后置语法

 

在 C++11 中增加了返回类型后置(trailing-return-type,又称跟踪返回类型)语法,将 decltype 和 auto 结合起来完成返回值类型的推导。

 

返回类型后置语法是通过 auto 和 decltype 结合起来使用的。上面的 add 函数,使用新的语法可以写成:

 

template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u){
    return t + u;
}

  

 

posted @ 2021-09-01 18:06  默行于世  阅读(1154)  评论(0编辑  收藏  举报