xmllmx
xmllmx

Reputation: 42379

Why is a variable not an lvalue in C++?

#include <type_traits>

int main()
{    
    int n;
    n = 0;

    // failure!
    static_assert(std::is_lvalue_reference_v<decltype(n)>); 
}

n can be put on the left side, so it should be obviously an lvalue.

Why does the static_assert fail?

Upvotes: 4

Views: 293

Answers (2)

decltype has special rules for id-expressions, deducing their type without regard to value category. If you want it to deduce a type based on the value category an id-expression normally has, you can surround the id-expression in parenthesis:

static_assert(std::is_lvalue_reference_v<decltype((n))>); 

(n) has the same type and value category as n in the type system, but isn't treated specially by decltype. Since the expression is an lvalue, the deduced type will be of an lvalue reference type.

Upvotes: 4

lubgr
lubgr

Reputation: 38315

n is indeed an lvalue reference, but decltype(n) returns int, and not int&. This mechanism is based on the way template type deduction works. It allows you such declarations and initializations:

int n = 0;

decltype(n) m = 42;

If decltype(n) were to yield int&, the above snippet wouldn't even compile. You can hence make the compiler happy with

static_assert(std::is_lvalue_reference_v<decltype(n)&>); 
static_assert(std::is_lvalue_reference_v<std::add_lvalue_reference_t<decltype(n)>>); 

but I guess this was not the point in the first place.

Upvotes: 2

Related Questions