Search code examples
c++c++11constantsdecltype

Is converting decltype's expression from constant l-value into an r-value discards `const` too?


Here I want to know how type specifier decltype works:

const int& rci = 5;// const ref bound to a temporary
decltype (rci) x = 2;
decltype (rci + 0) y = 10;
// ++x; // error: increment of read-only reference ‘x’|
++y; // why does this work

std::cout << typeid(x).name() << std::endl; // i
std::cout << typeid(y).name() << std::endl; // i
  • Why y has only type int rather than const int?

  • Does converting a constant lvalue into an rvalue discards in addition to reference operator, const qualifier too?

  • Why typeid shows that the type of x is just i but not const int&?


Solution

  • > Why y has only type int rather than const int?

    Because (rci + 0) is a prvalue, and prvalues of primitive types have const stripped.

    > Does converting a constant lvalue into an rvalue discards in addition to reference operator, const qualifier too?

    For non-class types, const qualifier is discarded. From the standard:

    7.3.1.1
    [...] If T is a non-class type, the type of the prvalue is the cv-unqualified version of T.

    > Why typeid shows that the type of x is just i but not const int&?

    From cppreference:

    In all cases, cv-qualifiers are ignored by typeid (that is, typeid(const T) == typeid(T)).