How to Determine Programmatically If an Expression Is Rvalue or Lvalue in C++

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



Leave a reply



Submit