深入学习C++ 关键字:auto

133 阅读3分钟
关键字:
    auto    //自动推导类型
            //auto i = 4; 此时i的类型自动推导为int
            
需要注意的时auto的自动推导并不是100%可靠的。这与它的推导规则有关。
已知变量:
    expr //expr是变量名,它可以是我们已知的任何类型
求:     
    paramType t = expr 中的t是什么类型 //paramType可以是auto, auto*, auto&, auto&&
推导规则1: ParamType == auto
    1. 如果expr是引用类型则忽略引用(比如int& -> int2.1.的基础上,如果expr还有顶层const修饰符则忽略它(比如int* const -> int*)
    3. expr剩下的类型就是 t 的类型
    
示例:
int x = 1;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

auto a1 = x;    //a1的类型为int
auto a2 = cx;   //a2的类型为int
auto a3 = rx;   //a3的类型为int
auto a4 = crx;  //a4的类型为int(通过1.crx的类型变为了const int,通过2.变为了int)
auto a5 = px;   //a5的类型为int*
auto a6 = cpxc; //a6的类型为const int*
推导规则2:ParamType == auto*
    1. 先当作ParamType == auto进行推导
    2.1.的基础上得到的类型与 * 做并集(比如int* 与 * 并集得到int*)
    
示例:
int x = 1;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

auto* a1 = &x;    //a1的类型为int*
auto* a2 = &cx;   //a2的类型为int*(&cx相当于const int*)
auto* a3 = ℞   //a3的类型为int*(&rx相当于int&*)
auto* a4 = &crx;  //a4的类型为const int*(&crx相当于const int&*)
auto* a5 = px;   //a5的类型为int*
auto* a6 = cpxc; //a6的类型为const int*
推导规则3:ParamType == auto&
    1. 如果expr是引用类型则忽略引用
    2.1.的基础上得到的类型与 & 做并集(比如int 与 & 并集得到int&)
    
示例:
int x = 1;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

auto& a1 = x;    //a1的类型为int&
auto& a2 = cx;   //a2的类型为const int&
auto& a3 = rx;   //a3的类型为int&
auto& a4 = crx;  //a4的类型为const int &
auto& a5 = px;   //a5的类型为int*&
auto& a6 = cpxc; //a6的类型为const int* const&
推导规则3:ParamType == auto&&
    1. 如果expr是一个左值,使用推导规则3
    2. 如果expr是一个右值,在推导规则1的基础上与&&做并集
    
示例:
int x = 1;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

auto&& a1 = x;    //a1的类型为int&
auto&& a2 = cx;   //a2的类型为const int&
auto&& a3 = rx;   //a3的类型为int&
auto&& a4 = crx;  //a4的类型为const int &
auto&& a5 = px;   //a5的类型为int*&
auto&& a6 = cpxc; //a6的类型为const int* const&
auto&& a7 = 27;   //a7的类型为int&&(因为27是右值)
补充:
    在面对数组类型时,数组类型将会退化为指针(int[3]退化为int*)
    在面对函数时,函数也会退化为指针(void(int)退化为void*(int))
    
那么auto在进行推导时,会以退化类型为准
以上的推导规则同样适用于模板
    template<typename T>
    void f(ParamType t);
    f(expr);
auto独有的:
    int x = {27};
    int x1{22};

    auto t = x;   //t的类型时std::intializer_list<int>
    auto t1 = x1; //t的类型时std::intializer_list<int>

原因是因为{}其实是一个模板