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 int
s 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...");
}
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");