jeudi 24 octobre 2019

Is cppreference using the term "[Object's] identity" is two inconsistent meanings for c++11 and for c++17?

I thought I've managed to fully understand (with the help of other SO questions, thanks) the C++17's change regarding value categories, but now I've noticed this problem which suggests I don't really understand them.

In C++11, there was a "has identity / can be moved from" equivalence and the definition of what "identity" means is still present in c++17's cppreference:

has identity: it's possible to determine whether the expression refers to the same entity as another expression, such as by comparing addresses of the objects or the functions they identify (obtained directly or indirectly).

In C++17, "has identity / can be moved from" is no longer true, but the new definition is also based on the concept of "identity":

a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;

My question/misunderstanding is: is this the same meaning of "identity", or is it a different "identity"? The way I understand it, the situation in c++17 is as follows:

A f();

A a = f(); // 1: f() is a prvalue expression, which is used to zero-copy-initialize a.
f();       // 2: f() is a prvalue expression, which gets converted to xvalue by temporary materialization
A&& r = f(); // 3: f() is a prvalue expression, which gets converted to xvalue by temporary materialization

In the 2nd and 3rd case, f() gets converted to an xvalue, which means it should have an identity. So I should be able to get its address, but I don't think I can. Of course, in the 3rd case I'm able to do "&r" as a separate command, but that's because A&& is an lvalue. Is taking the address via A&& what they mean in this case by "obtained directly or indirectly"? I assumed this can't be the correct answer, because in C++11 I can also easily do

A&& r = f(); // 4: f() is a prvalue expression. Temporary materialization does
             // not happen, the temporary (prvalue) gets its lifetime 
             // extended to match the lifetime of the reference
&r;

and yet at the moment of line "4" f() is still a prvalue which by definition has no identity (in c++11). So I assume just the fact I can bind it to A&& (of which, like any lvalue, I can take an address) is not enough to conclude that it has an identity, and yet in c++17 it looks to me like this would be the only possible interpretation?

Can you help me by determining which part of what I wrote is incorrect? Or is it correct, and the answer is simply that the word "identity" has changed its meaning?

Aucun commentaire:

Enregistrer un commentaire