Item2:理解 auto 类型推导
推导方式和[[1. 理解模板类型推导]]一致,下面讨论不同点:
在初始化时,采用auto声明变量相比于采用固定类型声明变量更具优势。下列声明都能通过编译,但是结果却并不相同:
1 | auto x1 = 27; // 类型是int,值是27 |
当用于auto声明变量的初始化表达式是使用大括号时,推导所得类型就属于std::initializer_list<int>。如果类型推导失败(例如大括号里的值类型不一样),代码就不通过编译:
1 | auto x5 = {1,2,3.0}; // 错误,推导不出std::initializer_list<T>中的T |
这里发生了两次类型推导:
auto的使用:x5的类型需要推导,由于x5的初始表达式是用大括号,所以x5必须推导为一个std::initializer_list。std::initializer_list<T>中T的推导:std::initializer_list是个模板,需要根据某个类型T产生类型std::initializer_list<T>,所以T的类型需要被推导出来。
但是,对于普通模板而言,不会自动识别为std::initializer_list:
1 | template<typename T> |
又但是,如果指定模板中的param为std::initializer_list<T>,则在T的类型未知的情况下,模板类型推导机制会推导出T应该的类型:
1 | template<typename T> |
总结
- 在一般情况下,
auto类型推导和模板类型推导是一模一样的,但是auto类型推导会假定用大括号括起的初始化表达式代表一个std::initializer_list,但模板类型推导却不会。 - 在函数返回值或
lambda式的形参中使用auto, 意思是使用模板类型推导而非auto类型推导。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 肖恩的博客!
评论
