Reputation: 42379
#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
Reputation: 170213
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
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