According to this document:
http://www.stroustrup.com/terminology.pdf
I have a couple of questions around these.
a. What's the example of an x-value having identity? The following isn't legal:
Foo f;
&std::move(f);
b. I could overload the &-operator of class Foo and make it return this so that the following becomes legal:
&Foo(5);
But pr-values like Foo(5) cannot have identity. Or is there a subtler interpretation of identity?
The following from Stroutrup's The C++ Programming Language might clear this question up:
void f(vector<string>& vs)
{
vector<string>& v2 = std::move(vs); // move vs to v2
// ...
}
Here, std::move(vs) is an xvalue: it clearly has identity (we can refer to it as vs), but we have explicitly given permission for it to be moved from by calling std::move() (§3.3.2, §35.5.1).
For practical programming, thinking in terms of rvalue and lvalue is usually sufficient.
Or is there a subtler interpretation of identity?
The document you linked contains these two definitions:
- “has identity” – i.e. and address, a pointer, the user can determine whether two copies are identical, etc.
- “can be moved from” – i.e. we are allowed to leave to source of a “copy” in some indeterminate, but valid state
Taking a look at the Standard we can gather the definition of an object (as per §1.8/1) is:
An object is a region of storage.
that as per, §1.7/1:
Every byte has a unique address.
has an address. This means that the definition is awfully broad and includes pretty much every object of any type of value (rvalue, xvalue, prvalue, lvalue, etc..).
What's the example of an x-value having identity?
The standard itself gives a list of expressions that generates xvalues (at §5/7):
An expression is an xvalue if it is:
- the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,
- a cast to an rvalue reference to object type,
- a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or
- a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.
In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether namedornot.
And as a follow up few examples are given. Here's an extension to them:
struct A { int m; };
A&& operator+(A, A);
A a;
A b;
a + b; // xvalue
A&& f();
f(); // xvalue
f().m; // xvalue
A a;
static_cast<A&&>(a); // xvalue
std::move(a); // xvalue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With