Search code examples
c++c++11rvalue-referencedecltypervalue

Why is the result of "decltype(i+j)" not an rvalue reference?


I'm trying to come up a simple example for an operation that results in a rvalue.

This test case should have worked, but surprisingly (to me), the result of adding two ints is not an rvalue (reference). What am I missing here?

void test(int i, int j)
{
    // this assert should pass, but fails:
    static_assert(std::is_same<decltype(i + j), int&&>(), "i + j should be a rvalue"); 
    // this assert passed, but should fail:
    static_assert(std::is_same<decltype(i + j), int>(), "this assert should fail...");
}

Solution

  • i + j is a prvalue expression,

    A prvalue ("pure rvalue") expression is an expression that does not have identity and can be moved from.

    a + b, a % b, a & b, a << b, and all other built-in arithmetic expressions;

    not a xvalue,

    An xvalue ("expiring value") expression is an expression that has identity and can be moved from.

    And decltype specifier yields T for prvalue, not T&&.

    a) if the value category of expression is xvalue, then decltype yields T&&;
    b) if the value category of expression is lvalue, then decltype yields T&;
    c) if the value category of expression is prvalue, then decltype yields T.

    You can make it xvalue by std::move:

    static_assert(std::is_same<decltype(std::move(i + j)), int&&>(), "std::move(i + j) is a xvalue then this static_assert won't fail");