自动类型推导

auto关键词

C++03及之前的标准种,auto放在变量声明之前,声明变量为自动变量(还有一种为静态变量 static变量)的存储策略。但是这个关键字常省略不写。C++11中,auto关键字放在变量之前,作用是在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型。

注意点

  • auto 变量必须在定义时初始化,这类似于const关键字
auto a1 = 10;  //正确
auto b1;   //错误,编译器无法推导b1的类型
b1 = 10;
  • 定义在一个auto序列的变量必须始终推导成同一类型
auto a4 = 10, a5{ 20 };   //正确
auto b4{ 10 }, b5 = 20.0; //错误,没有推导为同一类型
  • 如果初始化表达式是引用或const,则去除引用或const语义
int a{ 10 }; int& b = a;
auto c = b;   //c的类型为int而非int&(去除引用)
const int a1{ 10 };
auto b1 = a1; //b1的类型为int而非const int(去除const)
  • 如果auto关键字带上&号,则不去除引用或const语意
int a = 10; int& b = a;
auto& d = b;//此时d的类型才为int&
const int a2 = 10;
auto& b2 = a2;//因为auto带上&,故不去除const,b2类型为const in
  • 初始化表达式为数组时,auto关键字推导类型为指针。
int a3[3] = { 1, 2, 3 };
auto b3 = a3;
cout << typeid(b3).name() << endl; //输出int * (输出与编译器有关)
  • 若表达式为数组且auto带上 & ,则推导类型为数组类型。
int a7[3] = { 1, 2, 3 };
auto& b7 = a7;
cout << typeid(b7).name() << endl; //输出int [3] (输出与编译器有关)
  • 初始化时的一些常见问题

(1)当我们非常希望能够在变量定义的时候,希望明确地指出变量的类型,而且不希望随便更改其类型,那么我们可以使用下面的方法

auto x = int{ 3 }; // 初始化列表
auto y = int{ 3.0 };// 编译器报错,初始化列表不能窄化
auto z = int(3.0);  // C风格的强制类型转换,z的值是整数3

(2)auto和初始化列表一起用时,要避免在一行中使用直接列表初始化和拷贝列表初始化

auto x{ 1 }, y = { 2 };  // 错误,不要同时使用直接和拷贝列表初始化

Classic C++ Style

 (经典C++风格)

Modern C++ Style

(现代C++风格)

int x = 42;

auto x = 42;

float x = 42.;

auto x =42.f;          //f代表float

unsigned long x = 42;

auto x = 42ul;        //ul代表unsigned long

std::string x = "42";

auto x = "42"s;      //c++14

chrono::nanoseconds x{ 42 };

auto x = 42ns;       //c++14

int f(double);

auto f (double) -> int;    或   auto f (double) { /*…*/ };     或

auto f = [](double) { /*… */ };  //匿名函数

  •  C++14中,auto可以作为函数的返回值类型和参数类型

decltype关键字

在编译时期推导一个表达式的类型,而不用初始化,其语法格式有点像sizeof()。

#include <iostream>
using namespace std;
int fun1() { return 10; }
auto fun2() { return 'g'; } // C++14
int main()
{
    // Data type of x is same as return type of fun1()
    // and type of y is same as return type of fun2()
    decltype(fun1()) x; // 不会执行fun1()函数
    decltype(fun2()) y = fun2();
    cout << typeid(x).name() << endl;
    cout << typeid(y).name() << endl;
    return 0;
}

 

 
posted @ 2020-05-16 14:23  我等着你  阅读(378)  评论(0)    收藏  举报