c++ - auto 如何决定变量的类型?
问题描述
#include <iostream>
int main()
{
auto n {42};
cout << "The n has value of " << n <<
" and a size of " << sizeof(n) << endl; // Works as expected
}
#include <iostream>
int main()
{
auto n = {42};
cout << "The n has value of " << n <<
" and a size of " << sizeof(n) << endl; // Does not work!
}
这是为什么?在“A Tour of C++”中明确指出:
1.4.2 初始化 在一个对象可以使用之前,它必须被赋予一个值。C++ 提供了多种表示初始化的符号,例如上面使用的 =,以及基于花括号分隔的初始化列表的通用形式:
double d1 = 2.3; // initialize d1 to 2.3
double d2 {2.3}; // initialize d2 to 2.3
double d3 = {2.3}; // initialize d3 to 2.3 (the = is optional with { ... })
complex<double> z2 {d1,d2};
complex<double> z3 = {d1,d2}; // the = is optional with { ... }
=
是可选的{}
。
那么,为什么会这样呢?
解决方案
这受[dcl.type.auto.deduct]的规则约束,特别是[dcl.type.auto.deduct]/1和[dcl.type.auto.deduct]/4 [强调我的]:
[dcl.type.auto.deduct]/1
占位符类型推导是将包含占位符类型的类型替换为推导类型的过程。
[dcl.type.auto.deduct]/4
如果占位符是类型说明符,则使用模板参数推导的规则确定
auto
推导的类型T'
替换。通过用新发明的类型模板参数替换出现的 或,如果初始化是复制列表初始化,用 . 使用模板实参推导规则从函数调用中推导出一个值,其中是 函数模板形参类型,对应的实参是。如果扣除失败,则声明格式错误。否则,通过将推导代入得到。[ 例子:T
P
T
auto
U
std::initializer_list<U>
U
P
e
T'
U
P
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int
—结束示例]
您的第二个示例是使用复制列表初始化,含义auto
被替换为,使用模板参数推导规则,std::initializer_list<U>
,其中U
进一步推导为int
。
auto n {42}; // deduced type is 'int'
auto m = {42}; // deduced type is 'std::initializer_list<int>'
这些规则特别适用于占位符类型扣除,因此不适用于非占位符类型的情况;op 的后一个示例已经指定了类型并且适用非类型扣除。
// no placeholder type: type is 'double', and 'd1'
// through 'd3' simply uses different ways to initialize
// an object of (non-class fundamental) type 'double'.
double d1 = 2.3; // copy initialization
double d2 {2.3}; // direct-list initialization; no narrowing allowed
double d3 = {2.3}; // copy-list-initialization (from C++11); no narrowing allowed
推荐阅读
- spring - 如何在 restcontroller 中使用不记名令牌来执行 getAll 方法
- javascript - 在把手中显示来自 MongoDB 的数据
- django - 如何在 django 模型中获得另一个相关结果
- ansible - 如何复制由 ansible find 产生的所有文件?
- ag-grid - AG Grid React 服务器端行模型中的自定义 CSV 导出
- intellij-idea - IntelliJ idea sbt 项目未在终端中显示颜色
- python - 根据 Python 中其他列中的值使用 Seaborn 绘图数据
- ssl - 尝试在 OVH VPS 服务器上创建 SSL 证书时出错
- ios - 如何让迷你控制器出现在 iOS 的 react-native-google-cast 中?
- python - 在 QLayout PyQT 5 中的 QLabel 类型棋盘上绘制棋子