cpp中 decltype的类型推导规则究竟是什么样的
why
decltype(a+b) 推导为 int
decltype(a = a*b) 推导为 int&
ps: 有文章说 a+b返回右值, a = a*b返回左值, 感觉这两个表达式都是返回右值啊?
whywhy
cpp中 decltype的类型推导规则究竟是什么样的
decltype(a+b) 推导为 int
decltype(a = a*b) 推导为 int&
ps: 有文章说 a+b返回右值, a = a*b返回左值, 感觉这两个表达式都是返回右值啊?
whywhy
引自免费微信小程序:皆我百晓生
在C++中,decltype
是一个编译器关键字,用于推导表达式或变量声明时的类型。它的类型推导规则主要遵循以下原则:
基本规则:对于一个表达式 e
,decltype(e)
会推导出表达式 e
的类型。这个类型可能是引用类型(如果表达式 e
是一个左值)或者非引用类型(如果表达式 e
是一个右值)。
e
是一个变量名时,decltype(e)
就是该变量的类型。e
是一个表达式时,decltype(e)
是表达式 e
的结果类型。右值与左值区别:
如果 e
是一个纯右值(比如算术表达式 a + b
),那么 decltype(a + b)
将推导出该表达式的类型,这里是 int
,因为整数相加的结果是整型的临时对象(右值)。
然而,当 e
是一个赋值表达式(如 a = a * b
)时,情况有所不同。尽管表面上看起来它也像是产生了一个新的值(右值),但根据C++标准,赋值表达式的类型实际上是“左值引用到被赋值对象的类型”。所以,在这个例子中,a
在赋值后依然是一个可修改的左值,因此 decltype(a = a * b)
推导出的是 int&
类型,即引用到 int
类型。
顶层 cv-限定符保留:如果表达式 e
是一个变量,则 decltype(e)
会保留该变量的顶层 const 或 volatile 限定符。
示例代码说明:
int a = 0, b = 0;
decltype(a + b) c; // c 的类型为 int
decltype((a)) d; // (a) 强制转换为左值,d 的类型为 int&
decltype(a = b) e; // e 的类型为 int&,注意这里不是推导赋值表达式的结果类型,而是推导 "a" 被赋值后的类型
// 示例验证
c = a + b; // 正确,c 是 int 类型
d = a; // 正确,d 是 int& 类型,可以绑定到左值
// e = 5; // 错误,e 是 int& 类型,不能直接赋予字面常量值
总结来说,decltype
对于表达式的处理是基于表达式的求值类别以及其作为左值或右值的性质来决定最终推导的类型。在实际应用中,理解这一点有助于编写更加灵活和准确的模板函数或其他依赖于类型推导的场景。