C++中的(x)类型

Fer*_*eak 21 c++ decltype language-lawyer c++14

鉴于:

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&
}
Run Code Online (Sandbox Code Playgroud)

(摘自Scott Meyer的Effective Modern C++).

现在,如果我找到了正确的段落,则第7.1.5.2节 C++标准的简单类型说明符[dcl.type.simple]说:

如果e是id-expression或类成员访问(5.2.5 [expr.ref]),则decltype(e)被定义为由e命名的实体的类型

而该部分的例子是:

struct A { double x; }

const A* a = new A();

decltype((a->x)); // type is const double&
Run Code Online (Sandbox Code Playgroud)

现在,我想知道为什么被decltype((x))推断出来是int&在书中.

Tar*_*ama 10

相关标准引用如下:

N4140 [dcl.type.simple]/4:对于表达式e,表示的类型decltype(e)定义如下:

  • 如果e是未加密码的id-expression或未加括号的类成员访问(5.2.5),decltype(e) 则是名为的实体的类型e.如果没有这样的实体,或者如果e命名了一组重载函数,那么该程序就会形成错误;
  • 否则,如果edecltype(e)x值T&&,T则是e的类型;
  • 否则,如果e是左值,decltype(e)T&,这里T是e的类型 ;
  • 否则,decltype(e)是的类型e.

由于x是一个左值,并且表达括弧,则第三个规则使用,所以decltype((x))int&.


Yak*_*ont 8

decltype 返回变量的声明类型,或表达式的"类型"(添加一些引用以指示l/r值).

这使它可用于两个不同的目的.有时这会造成混乱,但事实就是如此.

令牌x是一个变量.变量的类型是int.

令牌(x)变量,而是含有只是一个变量(真微不足道)的表达.因此,表达式的类型(由decltype确定)(x)int&.

表达式的类型x(如果你可以说服decltype给你;你不能)也是int&,但是decltype(ACTUAL_VAR_NAME)评估变量类型的规则是"胜利".

现在,以上都不是真的.实际的事实是标准的引用,它描述了编译器应该通过哪些步骤来确定decltype返回的类型.但这是一个有效的谎言,一个(如果标准的措辞证明有错误)可能表明标准在它不同意时有一个错误.


eer*_*ika 5

§7.1.6.4[dcl.spec.auto](草案n3797)

  1. ...如果占位符是decltype(auto)类型说明符,则函数的声明类型或函数的返回类型应仅为占位符.根据7.1.6.2中的描述确定为变量或返回类型推导出的类型,就好像初始化器是decltype的操作数一样.

§7.1.6.2[dcl.type.simple]

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

- 如果e是未表示的id-expression或未加密的类成员访问(5.2.5),则decltype(e)是e命名的实体的类型.如果没有这样的实体,或者e命名了一组过载的功能,那么该程序就会形成错误;

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

- 否则,如果e是左值,则decltype(e)是T&,其中T是e的类型;

- 否则,decltype(e)是e的类型

xis是一个未加括号的id-expression,因此返回类型推导为以下类型x:int

(x)不是一个加括号标识表达,这样的规则并不适用.但是,它一个(带括号的)左值表达式.因此推导出的类型是T&其中T是的类型x:int&

  • @downvoter答案中有错误吗?我怎样才能改进它? (2认同)

Col*_*mbo 5

[dcl.spec.auto]/7强制要求,粗略地说,返回类型是通过应用于语句中decltype的表达式获得的return.因此,正如评论所暗示的那样,我们正在寻找decltype((x)).恶魔般的规则介入:

在此输入图像描述

需要注意的是,因为表达式的第一点不适用括号.因此,我们得到int&.


decltype普通标识符和括号标识符的应用之间的区别在相应论文的修订版6中引入.参见修订版5,§2.3:

表示的类型decltype(e)定义如下:

  1. 如果e是形式(e1),decltype(e)则定义为decltype(e1).

这背后的理由大概如下:编写(x),程序员打算decltype不将操作数视为名称而是表达式 - 考虑其值类别.