Topic: Rvalues and qualifiers
Author: CornedBee <wasti.redl@gmx.net>
Date: Sun, 25 Oct 2009 10:56:51 CST Raw View
Hi,
C++03 [basic.lval]p9 (and also the most recent working draft):
"Class rvalues can have cv-quali ed types; non-class rvalues always
have cv-unquali ed types."
In C++03, this peculiar rule was essentially irrelevant. Making
rvalues of class types carry qualifiers means this:
struct S { void nonconst(); };
const S cs();
void foo() { cs().nonconst(); /* invalid */ }
This is important.
Making rvalues of non-class types *not* carry qualifiers, on the other
hand, is completely undetectable. It isn't even noticeable in
overloading, since top-level cv qualifiers in function parameters do
not participate in overloading rules. The qualifier conversion is
subsumed in the initialization of the parameter.
So we have a very unintuitive rule in the standard, but no one cares,
because it isn't noticeable. For all practical purposes, all rvalues
carry qualifiers.
Until C++0x. Because now we have at least two ways I'm aware of that
detect this distinction: decltype and rvalue references.
---------------------------------------
const int ci();
const std::string cs();
void f(int&&);
void g(std::string&&);
void test()
{
// the comma expressions prevent the special rule for function calls
decltype((0, cs())) vs; // type is const std::string.
vs = "Hello"; // invalid
decltype((0, ci())) vi; // type is int
vi = 0; // valid
f(ci()); // valid
g(cs()); // invalid
}
---------------------------------------
Try to explain this to the average C++ programmer.
What's the rationale behind this rule? For all I can see, it's a
misguided attempt to keep C compatibility, where rvalues never carry
qualifiers. But I don't think C has any way to detect this, so I don't
understand why this would be relevant. In C++0x, however, this rule
leads to hard-to-explain behavior that holds little advantage to
anyone - it makes the language harder to understand and to implement.
The only advantage that I see is that there needs to be no reasoning
about cv-qualifiers in operators, e.g.
---------------------------------------
const int ci = 100;
int i = 99;
decltype(ci + i) v; // no doubt about the type of this
---------------------------------------
But I feel that the language would be more intuitive if this was
handled for the expressions themselves, i.e. add rules for dropping
top-level cv qualifications to most operators. Notable exceptions are
the comma operator and the conditional operator.
Have I overlooked something?
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Mon, 26 Oct 2009 00:18:39 CST Raw View
On 25 Oct, 19:56, CornedBee <wasti.r...@gmx.net> wrote:
> Making rvalues of non-class types *not* carry qualifiers, on the other
> hand, is completely undetectable.
It can be detected via passing as an argument of function template:
template <class T>
void f(T &);
If the argument is non-const rvalue then f is not viable. If the
argument is const rvalue then f is viable. But there is a problem with
specification of constness of function's return type which I have
considered in
http://groups.google.ru/group/comp.lang.c++.moderated/browse_thread/thread/2bd606664e4371b6#
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]