How to determine programmatically if an expression is rvalue or lvalue in C++?
Most of the work is already done for you by the stdlib, you just need a function wrapper:
template <typename T>
constexpr bool is_lvalue(T&&) {
return std::is_lvalue_reference<T>{};
}
in the case you pass a std::string
lvalue then T
will deduce to std::string&
or const std::string&
, for rvalues it will deduce to std::string
Note that Yakk's answer will return a different type, which allows for more flexibility and you should read that answer and probably use it instead.
Detecting if expression is lvalue or rvalue in C
The C standard does not provide any method for detecting whether an expression is an lvalue or not, either by causing some operation to have different values depending on whether an operand is an lvalue or not or by generating a translation-time diagnostic message or error depending on whether an operand is an lvalue or not.
C implementations may of course define an extension that provides this feature.
About the closest one can get in strictly conforming C is to attempt to take the address of the expression with the address-of operator &
. This will produce a diagnostic message (and, in typical C implementations, an error) if its operand is not an lvalue. However, it will also produce a message for lvalues that are bit-fields or that were declared with register
. If these are excluded from the cases of interest, then it may serve to distinguish between lvalues and non-lvalues during program translation.
C How to identify rvalue and lvalue?
lvalue (from left-hand side (LHS) value) in something that refers to a memory (or register) storage and that you can assign values to. *p++
is an lvalue since it is a dereferenced pointer (i.e. refers to the location in memory that ptr
points to while the value of ptr
itself is the address of that location) and ++*ptr++
actually means: *ptr = *ptr + 1; ptr = ptr + 1;
- it increments the value pointed to by ptr
and then increments the pointer value itself. i++
is not an lvalue since it is the value of i
incremented by 1 and does not refer to a location in memory. You can think of such values as final - they cannot be further modified and can only be used as values to assign to lvalues. That's why they are called rvalues (from right-hand side (RHS) value).
LHS and RHS refer to both sides of the assignment expression A = B;
. A
is the LHS and B
is the RHS.
Empirically determine value category of C++11 expression?
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
Related Topics
How to Build Libcxx and Libcxxabi by Clang on Centos 7
Llvm Get Constant Integer Back from Value*
Can #If Pre-Processor Directives Be Nested in C++
Why am I Not Provided with a Default Copy Constructor from a Volatile
Find Four Elements in Array Whose Sum Equal to a Given Number X
Treat C Cstyle Array as Std::Array
Poco C++ - Net Ssl - How to Post Https Request
Why Copy Constructor Is Called When Passing Temporary by Const Reference
How to Edit and Re-Build the Gcc Libstdc++ C++ Standard Library Source
Noexcept, Stack Unwinding and Performance
How to Force Gcc to Link Unreferenced, Static C++ Objects from a Library
What Is Difference Between Const and Non Const Key
How to Check If Given Int Exists in Array
Creating a String List and an Enum List from a C++ MACro
This Case of Template Function Overloading Eludes My Understanding