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式。

考虑以下问题:

密西西比有多久?

这个问题有两个答案:

  1. 密西西比州长2,320英里。
  2. 密西西比是11个字母。

同样,当你询问x的types时, x是一个标识符,不清楚你是指用来声明该标识符的types(即与名称x相关的types),还是包含expression式的types唯一提到的标识符。 事实上,可能有两个不同的关键字(例如entity_typeexpr_type ),而不是一个重载的decltype 。 出于某种原因,委员会select了超出decltype这两种不同的用途。

来自decltype提案的作者之一J. Jarvi:

已经有一段时间了,但是我想(我想)记得:

从来没有考虑两个独立的关键字来区分这两种语义。 (引入新的关键字不是轻而易举的)。

关于decltype((x))语义的变化,核心工作组的讨论集中在把(x)看作一个expression式,而不是一个标识符,这个标识符可能更符合语言规则的“内部一致性”。

人们意识到这在某些情况下可能会造成混淆,但是共识(也许不是每个人的偏好)最终都要符合标准的先前对什么是标识符和什么是expression的定义。

你链接到[这个问题的例子]的例子确实令人惊讶。 那时,使用decltype(auto)从返回expression式中推导一个函数的返回types还不是语言的一部分,所以我不认为这个特定的用例是任何人的事情。