1

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

struct A {
    double x;
};
const A* a = new A();

decltype( a->x ) x3;

匹配1个案例,即:

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

但请注意:

如果一个对象的名称被括号括起来,它变成一个左值表达式

引导我提出以下问题:a->x如果不是左值表达式,它的类型是什么?

我什至不明白为什么

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

仅通过将其视为左值表达式这一事实评估为 a const&,实际上并没有看到链接。

4

2 回答 2

4

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

你只是感到困惑。

如果一个对象的名称被括号括起来,它变成一个左值表达式

那应该是

如果对象的名称带有括号,则 decltype 对它的处理方式不同。

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

于 2013-04-12T10:50:44.667 回答
2

The way to think about it is (IMHO) this:

decltype( a->x )

keeps/retrieves the information that x refers to a member variable, hence it gives you the declared type of the member variable. This is helpful because you couldn't extract that information if this would automatically turned into the next case:

decltype( (a->x) )

This is "just" an expression and therefore behaves like any other expression. It refers to whatever the expression returns, not what the expression references. The expression is an lvalue, it doesn't matter that it's a member variable. You explicitly throw away a part of the information that is available, expressing your intend of not being interested in what the object/member was declared as but only in the resulting type of the expression.

In other words: The first syntax gives you more information unless you explicitly decide you don't need them and use the second syntax.

于 2013-04-12T10:27:28.943 回答