auto 关键字是从c++11标准引入的,实际用起来还是非常爽的!
优点:
自动推导变量类型
可以更加突出强制转换的用意
缺点:
当发生非预期的隐式转换时,可能会出现无法预知的错误
分析:
众所周知,用迭代器去访问容器打起来挺麻烦的,总是要写一长段:
vectorvct; for(vector ::iterator it = vct.begin(); it != vct.end(); it++){...}
而使用auto关键字就能少打很多字:
vectorvct; for(auto it = vct.begin(); it != vct.end(); it++){...}
又或者当我们使用类型转换时,使用显示强转强制 auto 推导出想要的类型,更能表达出代码类型转换的用意:(《Effective Modern C++》中的例子)
// 返回double类型的计算函数 double calc(); // 假设在某处float精度已经足够用时,显然可以将计算结果转成float来储存 float output = calc(); // 或者 float output = (float)calc();
上述这种写法难以表明“我故意降低了函数的返回值精度”,但是这么却可以做到:
auto output = static_cast(calc());
关于缺点,假设有一个函数接受一个 Widget 并返回 一个 std::vector
vectorfeatures(const Widget& w); Widget w; bool highPriority = features(w)[5]; // 第5个元素表示 w 的优先级 processWidget(w, highPriority); // 根据优先级处理 w
若是对 highPriority 用 auto 来推导其类型时,代码依旧可以编译,但是行为则变得不可预期了:
auto highPriority = features(w)[5]; processWidget(w, highPriority); // 未定义行为!
为何会出现未定义行为?难道这里的 highPriority 不是 bool 类型吗?答案确实如此,从概念上来说,std::vector
当用 bool highPriority 去接收 std::vector 的返回值时,底层会做一个隐式转换,从 std::vector::reference 到 bool 。
而使用 auto ,则会自动推导成 std::vector::reference ,这种非预期内的隐式转换就是导致出现未定义行为的罪魁祸首!!!
最后附上《Effective Modern C++》中的要点:
“隐形”的代理型别可以导致 auto 根据初始化表达式推导出“错误的”型别。带显示型别的初始化物习惯用法强制 auto 推导出你想要的型别。



