【Effective Modern C++】第一章 类型推导:2. 理解 auto 类型推导

推导方式和1.理解模板类型推导一致,下面讨论不同点:

在初始化时,采用auto声明变量相比于采用固定类型声明变量更具优势。下列声明都能通过编译,但是结果却并不相同:

c++ 复制代码
auto x1 = 27; // 类型是int,值是27
auto x2(27); // 同上
auto x3 = {27}; // 类型是std::initializer_list<int>,值是{27}
auto x4{27}; //同上 

当用于auto声明变量的初始化表达式是使用大括号时,推导所得类型就属于std::initializer_list<int>。如果类型推导失败(例如大括号里的值类型不一样),代码就不通过编译:

c++ 复制代码
auto x5 = {1,2,3.0}; // 错误,推导不出std::initializer_list<T>中的T

这里发生了两次类型推导:

  1. auto的使用:x5的类型需要推导,由于x5的初始表达式是用大括号,所以x5必须推导为一个std::initializer_list
  2. std::initializer_list<T>T的推导:std::initializer_list是个模板,需要根据某个类型T产生类型std::initializer_list<T>,所以T的类型需要被推导出来。

但是,对于普通模板而言,不会自动识别为std::initializer_list

c++ 复制代码
template<typename T> 
void f(T param);

f({ 11, 23, 9 }); // 编译错误!无法推导T的类型

又但是,如果指定模板中的paramstd::initializer_list<T>,则在T的类型未知的情况下,模板类型推导机制会推导出T应该的类型:

c++ 复制代码
template<typename T> 
void f(std::initializer_list<T> initlist); 

f({ 11, 23, 9 }); // 编译通过!

总结

  • 在一般情况下,auto 类型推导和模板类型推导是一模一样的,但是 auto 类型推导会假定用大括号括起的初始化表达式代表一个 std::initializer_list,但模板类型推导却不会。
  • 在函数返回值或 lambda 式的形参中使用 auto , 意思是使用模板类型推导而非 auto 类型推导。

原著在线阅读地址

相关推荐
ShineWinsu6 小时前
对于C++:C++11中lambda、function、bind的解析
c++·面试·笔试·开发·lambda·bind·function
码匠许师傅6 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试
旖旎夜光7 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
汉字萌萌哒7 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
hy.z_7778 小时前
【C++】13. 继承
c++
汉字萌萌哒8 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
2401_890603408 小时前
C++ 继承
c++
果果燕9 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++
老洋葱Mr_Onion9 小时前
【C++】信息学奥赛CSP通关之路——CSP-J/S第一轮原创全真模拟试卷集(2026)卷四全卷解析
开发语言·c++
布莱克60510 小时前
理解 C/C++ 中的 void* 指针
c语言·c++