int i = 12;
decltype(i) x4; // type is int
decltype((i)) x5; // type is int&
我们从C ++ fundementals知道i
已经是lvaue了。
现在decltype(i)
等于表达式i
的类型,即int
。
现在按照规范/标准(i)
也是左值,decltype((i))
也应该以某种方式检查表达式(i)
的类型,它是左值并且与i
相同,也是T&
左值。但为什么标准突然需要decltype((i)&)
类型?
这非常令人困惑。因为如果它是decltype
,那么我同意这意味着int&
的{{1}}会更加清晰和准确。我在这里有点迷失为什么i
和(i)
两个解析为左值类型的结果导致不同类型的T
和T&
。
答案 0 :(得分:1)
首先,decltype
在实体和表达式上有不同的行为。
1)如果参数是未命名的id-expression,命名结构化绑定,则decltype产生引用的类型(在结构化绑定声明的规范中描述)。 (自C ++ 17起)
2)如果参数是未加密码化的id-expression或未加密闭的类成员访问表达式,则decltype将生成此表达式命名的实体的类型。如果没有这样的实体,或者参数命名了一组重载函数,那么该程序就是格式错误。
3)如果参数是T类型的任何其他表达式,并且 - a)如果表达式的值类别是xvalue,则decltype产生T&&amp ;; - b)如果表达式的值类别是左值,则decltype产生T&amp ;; - c)如果表达式的值类别是prvalue,则decltype产生T。
以下这一行:
请注意如果对象的名称带括号,则将其视为普通左值表达式,因此
decltype(x)
和decltype((x))
通常是不同的类型。
因此,根据规则2,i
是实体,因此decltype会生成i
的确切类型,即int
。根据规则3和特别排除的行(上图),(i)
不是实体,而是左值表达式,因此decltype产生左值引用,即int&
。
(&(i)
和(i)++
是有效的表达式,因此(i)
是左值)