C++中为何decltype(a)为int类型,decltype(*p)却为int&类型
C++ decltype对
a和*p推导结果差异原因 问题复现代码
#include <iostream> int main() { int a=3; int *p=&a; decltype (a) k1; decltype (*p) k2; return 0; }
编译报错信息:
Declaration of reference variable 'k2' requires an initializer
核心原因:decltype的分情况推导规则
你看到的“decltype对可作为左值的表达式返回引用类型”的描述是不完整的,漏掉了decltype最高优先级的特殊匹配规则:
- 当decltype的操作数是没有括号包裹的单个变量/成员名时,推导结果直接取该变量声明时的原始类型,不会根据表达式的值类别做额外调整。
本例中a是单个无括号的int变量,因此decltype(a)推导结果为int,k1是普通int变量,不需要初始化也可以通过编译。 - 当decltype的操作数不是上述的单个无括号标识符,而是其他任意表达式时,才会根据表达式的值类别推导:
- 若表达式为左值(可放在赋值左侧,有稳定内存地址),推导结果为
T&(T为表达式的基础类型) - 若表达式为将亡值,推导结果为
T&& - 若表达式为纯右值(字面量、临时值等),推导结果为
T
本例中*p是指针解引用表达式,不属于单个无括号标识符,因此走第二条推导规则:解引用表达式的结果是左值,因此decltype(*p)推导结果为int&,引用类型必须在声明时绑定初始化,所以编译报错。
- 若表达式为左值(可放在赋值左侧,有稳定内存地址),推导结果为
验证规则的小测试
你可以尝试把a用括号包裹后再推导:
decltype((a)) k3;
此时(a)不再是单个无括号标识符,走表达式推导规则,a是左值,因此k3的类型也是int&,同样会报需要初始化的编译错误,和k2的情况完全一致。
内容的提问来源于stack exchange,提问作者Tyler durden
相关产品推荐
相关产品推荐

