C++ auto关键字


目录
  • auto 类型推导的语法和规则
    • 历史
    • 基本使用
    • auto的高级使用
  • auto的限制
  • auto的应用
    • 使用auto定义迭代器
    • 使用auto用于泛型编程

C++11 支持使用 auto 关键字来支持自动类型推导。

auto 类型推导的语法和规则

历史

过去:

在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。

auto 表示变量是自动存储的,这也是编译器的默认规则。

所以写不写都一样,一般也不写,这使得 auto 关键字的存在变得非常鸡肋。

现在:

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

基本使用

auto name = value;

auto 仅仅是一个占位符,在编译器期间它会被真正的类型所替代。

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
  • 当auto遇到&引用:第 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的限制

  • 使用auto时必须对变量初始化,才能推断出对应类型
  • auto 类型不能作为传入参数
  • auto 不能作用于类的非静态成员变量
  • auto 关键字不能定义数组
  • auto 不能作用于模板参数

auto的应用

使用auto定义迭代器

使用 stl 容器的时候,需要使用迭代器来遍历容器里面的元素。不同容器的迭代器有不同的类型,在定义迭代器时必须指明。而迭代器的类型有时候比较复杂,书写起来比较麻烦。

#include 
using namespace std;
int main(){
    vector< vector > v;
    auto i = v.begin();  //使用 auto 代替具体的类型
    return 0;
}

使用auto用于泛型编程

#include 
using namespace std;
class A{
public:
    static int get(void){
        return 100;
    }
};
class B{
public:
    static const char* get(void){
        return "http://c.biancheng.net/cplus/";
    }
};
template 
void func(void){
    auto val = T::get();
    cout << val << endl;
}
int main(void){
    func();
    func();
    return 0;
}

如果不使用auto关键字,需要增加模板参数:

#include 
using namespace std;
class A{
public:
    static int get(void){
        return 100;
    }
};
class B{
public:
    static const char* get(void){
        return "http://c.biancheng.net/cplus/";
    }
};
template   //额外增加一个模板参数 T2
void func(void){
    T2 val = T1::get();
    cout << val << endl;
}
int main(void){
    //调用时也要手动给模板参数赋值
    func();
    func();
    return 0;
}