I am reposting a comp.std.c++ Usenet discussion here because that group has become very unreliable. The last few posts I’ve submitted there have gone into the void, and activity has all but ceased. I doubt I’ve been banned and/or everyone else just lost interest. Hopefully all interested people will find this discussion, and there will be a general migration. Maybe then they will appoint a new moderator.
Hello!
With my current interpretation of draft N3126 w.r.t. the conditional
operator and xvalues, I expect the following assertions to hold:
int i = 0;
int& j = true? i : i;
int&& k = true? std::move(i) : std::move(i); // #2
assert(&i == &j); // Holds since C++98
assert(&i == &k); // Should this hold as well?
5.16/4 says:
If the second and third operands [to
the conditional operator] are
glvalues of the same value category
and have the same type, the result is
of that type and value category […]
Though, it doesn’t clearly say that the resulting glvalue refers to
one of the objects the glvalue operands referred to — or is this
implied because otherwise it would return a prvalue? Using GCC 4.5.1
in C++0x mode the second assertion fails. The reference k seems to
refer to some temporary object. Can somebody clarify whether the
comiler is allowed to create such a temporary in case both operands
around the colon are xvalues of the same type?
I’m currently assuming GCC is buggy and/or not up-to-date with respect
to xvalues.
The followup question is: Wouldn’t it be nice to be able to detect the
value category of an expression? If we ignore the conditional operator
we can detect the value category of an expression with decltype. But
what is
bool xvalue = std::is_rvalue_reference<
decltype( true ? std::move(i) : std::move(i) ) >::value;
supposed to yield? Using GCC 4.5.1, the xvalue variable is initialized
with false. Is this conforming to the current standard draft?
TIA,
Sebastian
I think GCC 4.5.1 is nonconforming wrt §5.16/4. Have you filed a bug report?
Anyway, I think it is conforming with that ternary operator code.
decltypeis defined by §7.1.6.2/4:decltypeworks by fetching the appropriate declaration and returning the desired type from it. It has little intelligence with respect to non-overloaded operators. Perhaps another pointeis an xvalue, decltype(e) isT&&, whereTis the type ofewould be in order, particularly since, as written, xvalues get treated as prvalues. Furthermore, your expression corresponds exactly to the definition of
std::common_type(§20.7.6.6/3).One straightforward workaround (to coin a phrase :vP ):