仅由变量标识符组成的表达式类型

时间:2019-06-17 18:14:14

标签: c++ language-lawyer

cppreference说:

  

可以将命名变量,函数,概念的特殊性(自C ++ 20起)或枚举器的标识符用作表达式。仅由标识符组成的表达式的结果是由标识符命名的实体。 [...]表达式的类型确定如下:

     

[...]     否则,表达式的类型与名为的实体的类型相同。

这不是错误吗?如果实体是参考,例如:

int &a = ...

然后a作为实体的类型为int &,但是a作为表达式的类型仅为int,不是吗?表达式的类型为never a reference

  

[...]每个表达式都有一些非引用类型

奖金问题:a的类型(作为表达式)是int还是int &,这有关系吗?如果是,它在哪里有作用?


注意:decltype使用相同的措词:

  

如果参数是未括号化的id表达式或未括号化的类成员访问表达式,则decltype会产生该表达式命名的实体的类型

但是很明显,decltype(a)int &

2 个答案:

答案 0 :(得分:1)

这是标准(草稿)所说的:

  

[expr.type]表达式/类型

     

如果表达式最初的类型为“对T的引用”,则在进行任何进一步分析之前,将类型调整为T。 ...

因此,很明显,表达式可以具有引用类型-最初是在调整类型分析之前。

  

“每个表达式都有一些非引用类型”是不是?

取决于您的解释方式。表达式可以(最初)具有非引用类型,但是所有表达式都具有某种非引用类型(调整后),用于类型分析。

  

[expr.prim.id.unqual]表达式/不合格的名称

     

结果是由标识符表示的实体。 ...如果实体是类型T的模板参数的模板参数对象... [不适用] ...否则,表达式的类型就是结果的类型。 [注意:类型   如果它是cv合格或参考类型,则将按照7.2.2中的描述进行调整。 —尾注] ... [示例:

void f() {
    float x, &r = x;
    [=] {
        decltype(x) y1;        // y1 has type float
        decltype((x)) y2 = y1; // y2 has type float const& because this lambda
                               // is not mutable and x is an lvalue
        decltype(r) r1 = y1;   // r1 has type float&
        decltype((r)) r2 = y2; // r2 has type float const&

    };
}
     

—结束示例]


  

Decltype说明符[dcl.type.decltype]

     

...如果e是未括号的id表达式或...,则decltype(e)是e命名的实体的类型。

答案 1 :(得分:0)

  

这不是错误吗?

不。 a的类型为int。是的,这只是在类型调整之前,但是由于总是发生,因此谈论具有引用类型的表达式是没有意义的,因为引用会立即消失。

  

这是否重要,a的类型(作为表达式)是int还是int &?如果是,它在哪里有作用?

这基本上是在问为什么我们根本需要值类别。基本上,由于右值引用有时是xvalues,有时是lvalues,它将破坏移动语义。