类型推导auto 和 decltype

一、auto 的规则

  1. auto 不能出现二义性
const auto a = 1, b = 1.0;//编译报b错误
  1. auto 只相当于一个类型声明的"占位符"
const auto a = 1, b; //编译器报错,必须给b赋值,让编译推导出类型

二、auto 的推导规则
1.auto 不声明为指针,也可以推导出指针类型

int x = 0; 
auto *b = &x; //auto 被推导为int  
auto & c = x;  // auto 被推导为int *
  1. 当表达式是一个引用类型的时候,auto 会把引用类型抛弃,直接推导成原始类型
auto &a = x;
auto b = a; //b 为int 类型
  1. 当表达式中带有const 或者volatile属性时,auto 会把const 属性抛弃掉,推导成non-const 类型
const int a = 1;
auto b = a;//b 类型为int
  1. 当const 和引用符号&结合时,会保留const
const int &a = x;
auto &b = a;//b 为const int &类型

通过上述,可以总结出两条规则:
1)当不声明为指针或引用时,auto 的推导结果和初始化表达式抛弃引用和cv(const 或 volatile)限定符后的类型一致
2) 当声明为指针或引用时,auto 的推导结果将保持初始化表达式的cv属性

二. auto 的限制

  1. auto 不能用于函数参数声明
void func(auto a = 1){} //编译器报错
  1. auto 无法定义数组
int arr[10] = {0};
auto rr[10] = arr; //auto 无法定义数组
  1. auto 无法推导出函数目标的参数
Bar<int> bar;
Bar<auto> bb = bar; //error,
  1. 用于成员变量时,auto 仅支持static const 的整型或者枚举型
class A
{
public:
    A();
    ~A();
private:
    static const  auto a = 1;//只有这种auto 才是对的,其他的方式在成员变量中都是错的
}; 

三、什么时候和正确的使用auto

  1. 使用stl容易遍历的时候,可以使用auto 来简化
    喜欢使用stl容易的同学,肯定对迭代器长长的类型很痛恨,代码写出来也不够简洁,如下对比
        std::map<int, int> mapData;
    mapData.insert(1, 1);
    std::map<int, int>::iterator iter = mapData.begin(); //c98
    auto iter11 = mapData.begin();//c++11,比c98简洁许多,效果确实一样
  1. 利用auto自动得出正确类型
    string str = "ttt";
    unsigned n = str.find("ABC");
        if (n == string::npos)
        {
            std::cout << "not find";
        }
        else {
            std::cout << "find";
        }
上述代码,在32位程序中不会出现问题,但是64位系统中呢,为什么会出现结果为:find。这是因为string::npos的类型为size_type,它在32位系统表示长度与unsigned一样,但是在64位系统中则比unsigned能表示的最大值要大,于是出现了bug。
这个时候使用: auto n = str.find("ABC")则不会出现这个问题,他会正确推导出返回值的类型
  1. 正确使用auto
auto n = 1024 * 1024 * 1024 * 5;
char* buf = new char[n];
上述代码不会报错,但是将auto改成const int,在有些严格的编译器下就会报错,不能分配这么大内存,内存不足
  1. auto 不是万能的
    有些普通类型会出错的问题,auto 也会出错,如:
std::vector<int> bigVector;
for (unsigned i = 0; i < bigVector.size(); ++i)
{ ... }
如果bigVector非常大,超过unsigned能表示的最大范围,此循环会变为无限循环,这时将unsigned改成auto 也不能完全避免
对于简单类型,auto的行为非常糟糕。是的,在最简单的情况下(自动x = y)它可以工作,但是一旦有其他构造,其行为就变得更加不可预测。更糟糕的是,错误将更难以发现,因为乍一看变量的类型并不那么明显。作为简单的凡人,这种情况,最好明确地指定类型。

四、decltype关键字的规则
decltype 用来推导表达式类型

  1. 语法格式
    decltype(exp) //exp表示一个表达式
  2. 推导规则
    1)exp是标识符、类访问表达式,decltype(exp) 和exp的类型一致
    2)exp是函数调用,decltype(exp) 和返回值的类型一致
    3)若exp是左值,则decltype(exp) 是exp类型的左值引用,否则和exp类型一致
  1. 对于纯右值,只有类类型可以携带cv限定符,普通类型一般会忽略cv限定符
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值