Question

according to http://en.cppreference.com/w/cpp/language/decltype

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

decltype( a->x ) x3;

match 1 case, i.e:

If the argument is either the unparenthesised name of an object/function, or is a member access expression (object.member or pointer->member), then the decltype specifies the declared type of the entity specified by this expression.

but this note:

if the name of an object is parenthesised, it becomes an lvalue expression

lead me to the following question: what is the type of a->x if it is not a lvalue expression?

I don't even get why

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

is evaluated as a const& only by the fact that it is considered as a lvalue expression, don't really see the link.

Was it helpful?

Solution

lead me to the following question what is the type of a->x if it is not a lvalue expression ?

You are simply confused.

if the name of an object is parenthesised, it becomes an lvalue expression

That should be

if the name of an object is parenthesized, it is handled different by decltype.

Both the parenthesized and nonparenthesized things are lvalue expressions. If you don't parenthesize, then decltype does not inspect the type of the expression, but the type used by the declaration that the name lookup found the name to refer to (for example, it could be int&& if name lookup resolves it to an rvalue reference variable, but the type of the expression is int and is an lvalue).

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top