In the cpprefernce section: Value categories, it states that "the member of object expression, where a is an rvalue and m is a non-static data member of non-reference type" is an xvalue. In the standard (I found in: N4140, the draft C++14 standard) it states (on page 87) that "An expression is an xvalue if it is... a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue."
I wanted to check my understanding of this with the following code:
struct B { // B for Boring...
int i{0};
};
template <typename T> struct V {
V() { cout << "V" << endl; }
};
template <typename T> struct V<T &> { // Partial Specialization
V() { cout << "V&" << endl; }
};
template <typename T> struct V<T &&> { // Partial Specialization
V() { cout << "V&&" << endl; }
};
int main() {
int i{1};
V<decltype((1))> v1; // V
V<decltype((i))> v2; // V&
V<decltype((move(i)))> v3; // V&&
V<decltype((B().i))> v4; // V, why not V&&?
V<decltype((move(B()).i))> v5; // V&& as expected
}
If my calculations are correct, then B().i
is a "member of object expression, where [B()
] is an rvalue," and according to the reference that expression should be an xvalue, and the type returned by decltype
should be int&&. Note that I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
, and I tried it with no flags and with -std=c++14
.
(To be clear, I'm also checking my understanding of "decltype" here, but the standard I previously linked to and the reference agree verbatim and quite clearly on the behavior of decltype).
Sorry, that wasn't a question... Am I right? Should the reference be updated to clarify this behavior?