decltype行为背后的理由是什么?

时间:2016-10-27 10:22:00

标签: c++ c++11 c++14 decltype type-deduction

正如我在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&。这更令人困惑。我不知道这种行为是否符合标准。

3 个答案:

答案 0 :(得分:35)

他们想要一种方法来获得标识符的声明类型。

他们还想要一种方法来获取表达式的类型,包括有关它是否是临时的信息。

decltype(x)给出标识符x的声明类型。如果您传递decltype不是标识符的内容,则会确定类型,然后为左值添加&,为xvalues添加&&,为prvalues添加任何内容。

从概念上讲,您可以将其视为变量类型与表达式类型之间的差异。但这并不是标准对它的描述。

他们可以使用两个不同的关键字来表示这两件事。他们没有。

答案 1 :(得分:24)

需要区分实体和表达。

考虑以下问题:

  

密西西比州有多长时间?

这个问题有两个答案:

  1. 密西西比州长2,320英里。
  2. 密西西比州长11个字母。
  3. 同样,当您询问x的类型,x是标识符时,不清楚您是否表示用于声明该标识符的类型(即与该标识符关联的类型)名称x),或由唯一提及该标识符组成的表达式的类型。实际上,可能有两个不同的关键字(例如entity_typeexpr_type),而不是单个重载的decltype。出于某种原因,委员会选择对这两种不同用途重载decltype

答案 2 :(得分:18)

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

  

已经有一段时间了,但这就是我(我想)记住的事情:

     

用于区分这两种语义的两个单独的关键字   从未考虑过。 (引入新关键词不是轻易做到的。)

     

关于decltype((x))语义的变化,讨论了。{   相反,核心工作组将(x)视为一种表达方式   而不是标识符,可能更“内部一致”   语言规则。

     

人们意识到这可能会让一些人感到困惑   案件,但共识(虽然可能不是每个人的偏好)是   最终要符合标准的先前定义   什么是标识符,什么是表达式。

     

您链接到[此问题'示例]的示例确实令人惊讶。当时,推断一个   函数的返回类型使用decltype(auto)返回表达式   还不是语言的一部分,所以我认为这不是特别的用法   案件在任何人的雷达上。