Each expression in C++11 has a value category. One of lvalue, xvalue or prvalue.
Is there a way to write a macro that, given any expression as an argument, will produce a string "lvalue", "xvalue" or "prvalue" as appropriate?
For example:
int main() { int x; cout << VALUE_CAT(x) << endl; // prints lvalue cout << VALUE_CAT(move(x)) << endl; // prints xvalue cout << VALUE_CAT(42) << endl; // prints prvalue }
How could VALUE_CAT
be implemented?
C++ defines 3 value categories which represent the useful combination of these properties: lvalue (expressions with identity but not movable from), xvalue (expressions with identity that are moveable from), and prvalue (expressions without identity that are moveable from).
Walter Goodnow Everett classified values into the following eight categories; (1) economic values, (2) bodily values, (3) value of recreation, (4) value of association, (5) character values, (6) aesthetic values, (7) intellectual values, (8) religious values.
Prerequisites: lvalue and rvalue in C++, References in C++ “l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory.
An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.
decltype
can return the declared type of an entity (hence the name), but can also be used to query the type of an expression. However, in the latter case the resulting type is 'adjusted' according to the value category of that expression: an lvalue expression results in an lvalue reference type, an xvalue in an rvalue reference type, and a prvalue in just the type. We can use this to our benefit:
template<typename T> struct value_category { // Or can be an integral or enum value static constexpr auto value = "prvalue"; }; template<typename T> struct value_category<T&> { static constexpr auto value = "lvalue"; }; template<typename T> struct value_category<T&&> { static constexpr auto value = "xvalue"; }; // Double parens for ensuring we inspect an expression, // not an entity #define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value
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