#include using namespace std ; //https://stackoverflow.com/questions/15765893/what-is-the-reasoning-behind-the-naming-of-lvalue-and-rvalue //https://learn.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=msvc-170 //https://stackoverflow.com/questions/17357888/exact-difference-between-rvalue-and-lvalue template constexpr bool is_lvalue(T&&) { return is_lvalue_reference{}; } //Returns a rvalue int setValue() { return 6; } int global = 100; int& setGlobal() { return global; } int main() { int x1 = 100 ; //x1 is lvalue because it has an address //100 is a rvalue because it is temporary and does //not have a permanent address in memory. It may be stored //in a register but after the statement, //it's value is lost. cout << is_lvalue( x1 ) << endl ; cout << is_lvalue( 100 ) << endl ; // 100 = x1 ; //This produces a compiler error. //values1.cpp: In function ‘int main()’: //values1.cpp:20:6: error: lvalue required as left operand of assignment // 20 | 100 = x1 ; //The "100" does not have an address and is a rvalue and we cannot //put it to the left as it makes no sense. //The left of an assignment must be a lvalue . //setValue() = 100 ; //Compiler error as the function does not return a lvalue setGlobal() = 100 ; //The above is all right because the function // "setGlobal" returns a lvalue . int x2 = x1 ; //Here x2 is a lvalue and x1 is also a lvalue. int& x3 = x1 ; //x3 is a lvalue. There is a name. cout << is_lvalue( x3 ) << endl ; }