decltype行为的基本原理是什么?
正如我在C ++ 11中所理解的, decltype(expression)
用于推导给定expression式的完全相同types。 但是当expression式本身被放入括号中时,则推导types是左值对expression式types的引用 。 例如:
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& }
标准委员会select这种行为的理由是什么?
后记:
现在我观察到,至less在GCC 6.2实现的情况下,当括号中的expression式更复杂时,例如decltype((x + x))
,推导的types是T
,而不是T&
。 这更令人困惑。 我不知道这个行为是否是标准的。
他们想要一种方式来获得标识符的声明types。
他们还想要一种方法来获得expression式的types,包括关于它是否是临时的信息。
decltype(x)
给出标识符x
的声明types。 如果传递decltype
东西不是一个标识符,它决定了types,然后附加&
左值, &&
为xvalues,没有prvalues。
从概念上讲,您可以将其视为variablestypes与expression式types之间的区别。 但是这不是标准的描述。
他们可以使用两个不同的关键字来表示这两件事情。 他们没有。
有一些需要区分一个实体和一个expression式。
考虑以下问题:
密西西比有多久?
这个问题有两个答案:
- 密西西比州长2,320英里。
- 密西西比是11个字母。
同样,当你询问x
的types时, x
是一个标识符,不清楚你是指用来声明该标识符的types(即与名称x
相关的types),还是包含expression式的types唯一提到的标识符。 事实上,可能有两个不同的关键字(例如entity_type
和expr_type
),而不是一个重载的decltype
。 出于某种原因,委员会select了超出decltype
这两种不同的用途。
来自decltype
提案的作者之一J. Jarvi:
已经有一段时间了,但是我想(我想)记得:
从来没有考虑两个独立的关键字来区分这两种语义。 (引入新的关键字不是轻而易举的)。
关于
decltype((x))
语义的变化,核心工作组的讨论集中在把(x)
看作一个expression式,而不是一个标识符,这个标识符可能更符合语言规则的“内部一致性”。人们意识到这在某些情况下可能会造成混淆,但是共识(也许不是每个人的偏好)最终都要符合标准的先前对什么是标识符和什么是expression的定义。
你链接到[这个问题的例子]的例子确实令人惊讶。 那时,使用
decltype(auto)
从返回expression式中推导一个函数的返回types还不是语言的一部分,所以我不认为这个特定的用例是任何人的事情。