Decltype和左值表达式

decltype and lvalue expression

本文关键字:表达式 Decltype      更新时间:2023-10-16

根据http://en.cppreference.com/w/cpp/language/decltype

struct A {
    double x;
};
const A* a = new A();
decltype( a->x ) x3;

匹配1个大小写,即:

如果实参是对象/函数的未加括号的名称,或者是成员访问表达式(object。成员或指针->成员),则decltype指定该表达式指定的实体的声明类型。

但是这个注意:

如果一个对象的名字加上括号,它就变成了一个左值表达式

使我想到以下问题:如果a->x不是左值表达式,它的类型是什么?

我甚至不明白为什么

decltype((a->x)) x4 = x3; // type of x4 is const double& (lvalue expression)

被评估为const&只是因为它被认为是一个左值表达式,而不是真正看到链接。

使我想到以下问题:如果a->x不是左值表达式,它的类型是什么?

你只是糊涂了。

如果一个对象的名字加上括号,它就变成了一个左值表达式

应该是

如果对象的名称被括号括起来,则通过decltype对其进行不同的处理。

带括号和不带括号的内容都是左值表达式。如果不加括号,则decltype不检查表达式的类型,而是检查名称查找找到要引用的名称的声明所使用的类型(例如,如果名称查找将其解析为右值引用变量,则可能是int&&,但表达式的类型是int,并且是左值)。

思考这个问题的方法是(IMHO):

decltype( a->x )

保存/检索x引用成员变量的信息,因此它为您提供了成员变量的声明类型。这很有用,因为如果这将自动转换为下一个case,则无法提取该信息:

decltype( (a->x) )

这"只是"一个表达式,因此其行为与任何其他表达式一样。它指向表达式返回的,而不是表达式引用的。表达式是一个左值,它是不是成员变量并不重要。显式地丢弃了可用的部分信息,表示您不关心对象/成员声明为什么,而只关心表达式的结果类型。

换句话说:第一种语法给你更多的信息,除非你明确地决定你不需要它们而使用第二种语法。