正如我在C ++ 11中所理解的,decltype(expression)
用于推断给定表达式的完全相同类型。但是当表达式放入括号本身时,则推导类型是左值引用到表达式类型。例如:
int x;
decltype(x) y = x;
相当于int y = x;
,但
int x;
decltype((x)) y = x;
相当于int& y = x;
。
分别
decltype(auto) f1()
{
int x = 0;
return x; // decltype(x) is int, so f1 returns int
}
但
decltype(auto) f2()
{
int x = 0;
return (x); // decltype((x)) is int&, so f2 returns int&
}
标准委员会选择这种行为的理由是什么?
后记:
现在我观察到,至少在 GCC 6.2 实现的情况下,当括号中的表达式更复杂时,例如decltype((x + x))
,推导出的类型为T
,但是不是T&
。这更令人困惑。我不知道这种行为是否符合标准。
答案 0 :(得分:35)
他们想要一种方法来获得标识符的声明类型。
他们还想要一种方法来获取表达式的类型,包括有关它是否是临时的信息。
decltype(x)
给出标识符x
的声明类型。如果您传递decltype
不是标识符的内容,则会确定类型,然后为左值添加&
,为xvalues添加&&
,为prvalues添加任何内容。
从概念上讲,您可以将其视为变量类型与表达式类型之间的差异。但这并不是标准对它的描述。
他们可以使用两个不同的关键字来表示这两件事。他们没有。
答案 1 :(得分:24)
需要区分实体和表达。
考虑以下问题:
密西西比州有多长时间?
这个问题有两个答案:
同样,当您询问x
的类型,x
是标识符时,不清楚您是否表示用于声明该标识符的类型(即与该标识符关联的类型)名称x
),或由唯一提及该标识符组成的表达式的类型。实际上,可能有两个不同的关键字(例如entity_type
和expr_type
),而不是单个重载的decltype
。出于某种原因,委员会选择对这两种不同用途重载decltype
。
答案 2 :(得分:18)
来自decltype
提案的作者之一J. Jarvi:
已经有一段时间了,但这就是我(我想)记住的事情:
用于区分这两种语义的两个单独的关键字 从未考虑过。 (引入新关键词不是轻易做到的。)
关于
decltype((x))
语义的变化,讨论了。{ 相反,核心工作组将(x)
视为一种表达方式 而不是标识符,可能更“内部一致” 语言规则。人们意识到这可能会让一些人感到困惑 案件,但共识(虽然可能不是每个人的偏好)是 最终要符合标准的先前定义 什么是标识符,什么是表达式。
您链接到[此问题'示例]的示例确实令人惊讶。当时,推断一个 函数的返回类型使用
decltype(auto)
返回表达式 还不是语言的一部分,所以我认为这不是特别的用法 案件在任何人的雷达上。