#include <iostream>
int i=7;
const int& f(){return i;}
int main(){std::cout<<&"www"<<std::endl; // The expression "www" in this row is an lvalue expression, because string literals are arrays and every array has an address.
i; // The expression i in this row is an lvalue expression, because it refers to the same entity ...i; // ... as the entity the expression i in this row refers to.
int* p_i=new int(7);*p_i; // The expression *p_i in this row is an lvalue expression, because it refers to the same entity ...*p_i; // ... as the entity the expression *p_i in this row refers to.
const int& r_I=7;r_I; // The expression r_I in this row is an lvalue expression, because it refers to the same entity ...r_I; // ... as the entity the expression r_I in this row refers to.
f(); // The expression f() in this row is an lvalue expression, because it refers to the same entity ...i; // ... as the entity the expression f() in this row refers to.
return 0;}
x值
表达式E属于xvalue类别当且仅当它是
-调用函数的结果,无论是隐式还是显式,其返回类型是对返回对象类型的右值引用,或者
int&& f(){return 3;}
int main(){f(); // The expression f() belongs to the xvalue category, because f() return type is an rvalue reference to object type.
return 0;}
-转换为对象类型的右值引用,或
int main(){static_cast<int&&>(7); // The expression static_cast<int&&>(7) belongs to the xvalue category, because it is a cast to an rvalue reference to object type.std::move(7); // std::move(7) is equivalent to static_cast<int&&>(7).
return 0;}
-类成员访问表达式,指定非引用类型的非静态数据成员,其中对象表达式是xvalue,或
struct As{int i;};
As&& f(){return As();}
int main(){f().i; // The expression f().i belongs to the xvalue category, because As::i is a non-static data member of non-reference type, and the subexpression f() belongs to the xvlaue category.
return 0;}
#include <functional>
struct As{int i;};
As&& f(){return As();}
int main(){f(); // The expression f() belongs to the xvalue category, because it refers to an unnamed rvalue reference to object.As&& rr_a=As();rr_a; // The expression rr_a belongs to the lvalue category, because it refers to a named rvalue reference to object.std::ref(f); // The expression std::ref(f) belongs to the lvalue category, because it refers to an rvalue reference to function.
return 0;}
右值
表达式E属于右值类别当且仅当E既不属于左值也不属于xvalue类别。
struct As{void f(){this; // The expression this is a prvalue expression. Note, that the expression this is not a variable.}};
As f(){return As();}
int main(){f(); // The expression f() belongs to the prvalue category, because it belongs neither to the lvalue nor to the xvalue category.
return 0;}
void doesNothing(){}struct S{int x{0};};int x = 1;int y = 2;S s;
static_assert(IS_LVALUE(x));static_assert(IS_LVALUE(x+=y));static_assert(IS_LVALUE("Hello world!"));static_assert(IS_LVALUE(++x));
static_assert(IS_PRVALUE(1));static_assert(IS_PRVALUE(x++));static_assert(IS_PRVALUE(static_cast<double>(x)));static_assert(IS_PRVALUE(std::string{}));static_assert(IS_PRVALUE(throw std::exception()));static_assert(IS_PRVALUE(doesNothing()));
static_assert(IS_XVALUE(std::move(s)));// The next one doesn't work in gcc 8.2 but in gcc 9.1. Clang 7.0.0 and msvc 19.16 are doing fine.static_assert(IS_XVALUE(S().x));