C++11新特性学习:auto类型推导

Posted CodeBowl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11新特性学习:auto类型推导相关的知识,希望对你有一定的参考价值。

1.auto 类型推导

在 C++11 之前的版本(C++98 和 C++ 03)中,定义变量或者声明变量之前都必须指明它的类型,比如 int、char 等;但是在一些比较灵活的语言中,比如 C#、javascriptphp、Python 等,程序员在定义变量时可以不指明具体的类型,而是让编译器(或者解释器)自己去推导,这就让代码的编写更加方便。
C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不用手动指明变量的数据类型了。
auto 关键字基本的使用语法如下:

auto name = value;

name 是变量的名字,value 是变量的初始值。
注意:auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。或者说,C++ 中的变量必须是有明确类型的,只是这个类型是由编译器自己推导出来的。

auto 类型推导的简单例子

auto n = 10;
auto f = 12.8;
auto p = &n;
auto url = "http://c.biancheng.net/cplus/";

下面我们来解释一下:
• 第 1 行中,10 是一个整数,默认是 int 类型,所以推导出变量 n 的类型是 int。
• 第 2 行中,12.8 是一个小数,默认是 double 类型,所以推导出变量 f 的类型是 double。
• 第 3 行中,&n 的结果是一个 int* 类型的指针,所以推导出变量 p 的类型是 int*。
• 第 4 行中,由双引号""包围起来的字符串是 const char* 类型,所以推导出变量 url 的类型是 const char*,也即一个常量指针。

注意事项

1.使用auto类型推导的变量必须马上初始化。
2.推导不能有二义性,例如int n=1,m=1.55;这样就是冲突的,m也必须是int类型才可以。

auto的高级用法

auto 除了可以独立使用,还可以和某些具体类型混合使用,这样 auto 表示的就是“半个”类型,而不是完整的类型。请看下面的代码:
int x = 0;
auto p1 = &x; //p1 为 int ,auto 推导为 int
auto p2 = &x; //p2 为 int
,auto 推导为 int

auto &r1 = x; //r1 为 int&,auto 推导为 int
auto r2 = r1; //r2 为 int,auto 推导为 int
下面我们来解释一下:
• 第 2 行代码中,p1 为 int* 类型,也即 auto * 为 int ,所以 auto 被推导成了 int 类型。
• 第 3 行代码中,auto 被推导为 int
类型,前边的例子也已经演示过了。
• 第 4 行代码中,r1 为 int & 类型,auto 被推导为 int 类型。
• 第 5 行代码是需要重点说明的,r1 本来是 int& 类型,但是 auto 却被推导为 int 类型,这表明当=右边的表达式是一个引用类型时,auto 会把引用抛弃,直接推导出它的原始类型。
接下来,我们再来看一下 auto 和 const 的结合:

int  x = 0;
const  auto n = x;  //n 为 const int ,auto 被推导为 int
auto f = n;      //f 为 const int,auto 被推导为 int(const 属性被抛弃)
const auto &r1 = x;  //r1 为 const int& 类型,auto 被推导为 int
auto &r2 = r1;  //r1 为 const int& 类型,auto 被推导为 const int 类型

下面我们来解释一下:
• 第 2 行代码中,n 为 const int,auto 被推导为 int。
• 第 3 行代码中,n 为 const int 类型,但是 auto 却被推导为 int 类型,这说明当=右边的表达式带有 const 属性时, auto 不会使用 const 属性,而是直接推导出 non-const 类型。
• 第 4 行代码中,auto 被推导为 int 类型,这个很容易理解,不再赘述。
• 第 5 行代码中,r1 是 const int & 类型,auto 也被推导为 const int 类型,这说明当 const 和引用结合时,auto 的推导将保留表达式的 const 类型。
最后我们来简单总结一下 auto 与 const 结合的用法:
• 当类型不为引用时,auto 的推导结果将不保留表达式的 const 属性;
• 当类型为引用时,auto 的推导结果将保留表达式的 const 属性。

auto的限制

前面介绍推导规则的时候我们说过,使用 auto 的时候必须对变量进行初始化,这是 auto 的限制之一。那么,除此以外,auto 还有哪些其它的限制呢?

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

这个应该很容易理解,我们在定义函数的时候只是对参数进行了声明,指明了参数的类型,但并没有给它赋值,只有在实际调用函数的时候才会给参数赋值;而 auto 要求必须对变量进行初始化,所以这是矛盾的。
2) auto 不能作用于类的非静态成员变量(也就是没有 static 关键字修饰的成员变量)中。
3) auto 关键字不能定义数组,比如下面的例子就是错误的:

char url[] = "http://c.biancheng.net/";
auto  str[] = url;  //arr 为数组,所以不能使用 auto

4) auto 不能作用于模板参数,请看下面的例子:

template <typename T>
class A{
//TODO:
};
int  main(){
A<int> C1;
A<auto> C2 = C1;  //错误
return 0;
}

auto的应用

  1. 使用auto定义迭代器
int main(){
    vector< vector<float> > v;
    auto i = v.begin();  //使用 auto 代替具体的类型
    return 0;
}
  1. auto用于泛型编程
class A{
public:
    static int get(void){
        return "A::get()返回值";
    }
};
template <typename T>
void func(void){
    auto val = T::get();
    cout << val << endl;
}

以上是关于C++11新特性学习:auto类型推导的主要内容,如果未能解决你的问题,请参考以下文章

C++11 学习笔记-类型推导

C++ 学习笔记:C++11 新特性学习

新兵易学,老兵易用----C++(C++11的学习整理---如何减少代码量,加强代码的可读性)

C++学习笔记——auto/decltype 自动推导类型

C++学习笔记——auto/decltype 自动推导类型

C++学习笔记——auto/decltype 自动推导类型