C ++为什么decltype(* pointer)产生引用?

时间:2018-07-17 19:17:08

标签: c++ pointers reference language-lawyer decltype

我想知道为什么当我使用decltype (* pointer)时,它将变量的类型定义为引用。例如:

int i = 42, * p = & i;
decltype (* p) c = i;

现在c是一个引用(链接到i)。为什么它是引用而不是整数?我正在读Cpp Primer 5th。版。 P. 110这样说,我不明白为什么。

2 个答案:

答案 0 :(得分:4)

与显然流行的看法相反,*p的类型为int。来自[expr.unary.op]

  

一元*运算符执行间接操作:应用该表达式的表达式应为指向对象类型的指针或为函数类型的指针,并且结果为指向表达式所指向的对象或函数的左值。如果表达式的类型为“ T的指针”,则结果的类型为“ T”

decltype(*p)产生int&的原因是因为decltype的工作方式。来自[dcl.type.simple]

  

对于表达式e,由decltype(e)表示的类型定义如下:[...]

     
      
  • 否则,如果e是未括号化的id表达式或未括号化的类成员访问,则decltype(e)是e命名的实体的类型。如果没有这样的实体,或者如果e命名了一组重载函数,则程序的格式不正确;

  •   
  • 否则,如果e为x值,则decltype(e)为T &&,其中T为e的类型;

  •   
  • 否则,如果e为左值,则decltype(e)为T&,其中T为e的类型; [...]

  •   

此处的id表达式表示完全由可能带有括号的名称组成的表达式。

由于*p是类型int的左值表达式,不是非括号的id表达式或类成员访问权限,因此第三个项目符号适用,并且decltype(*p)int&。 / p>

值得注意的是,i是一个无括号的id表达式,因此第一个项目符号适用,decltype(i)int

答案 1 :(得分:4)

decltype(expr)将为您提供的类型取决于表达式的value category。如果expr不仅是 id-expression (即事物的名称),则规则基本上是:

  • 如果expr是类型T的xvalue,则decltype(expr)将是 T&&
  • 如果expr是类型T的左值,则decltype(expr)将 是T&
  • 否则,decltype(expr)将是T

在您的情况下,*p是类型int的左值。因此,decltype(*p)被定义为int&。如果要decltype给您int,则必须使表达式成为prvalue,例如通过应用@Cheers和hth建议的一元+运算符。 -Alf在上面的评论中。但是,在实际代码中最好避免使用这种神秘构造。出于可读性考虑,最好只使用std::remove_reference_t<decltype(*p)>