Re: C++0x: move() & a hypotheticyl language feature
on Mon Nov 10 2008, SG <s.gesemann-AT-gmail.com> wrote:
Hi!
The latest declaration of std::move according to N2798 is
template<RvalueOf T> RvalueOf<T>::type move(T&&);
where RvalueOf is defined to be
auto concept RvalueOf<typename T> {
typename type = T&&;
require Convertible<T&,type> && Convertible<T&&,type>;
}
template<typename T> concept_map RvalueOf<T&> {
typedef T&& type;
}
But a move is only interesting when the parameter is actually an
lvalue. In case of a rvalue parameter the function might return a
reference that's going to dangle once the evaluation of the expression
is completed. Example:
A&& aref = move(A()); // 'a' will be a dangling reference
This is because the information about the returned reference being a
local temporary is LOST. So, i was thinking whether it's okay to
replace the current move by a function like this:
template<typename T> T&& move(T& x) { return x; }
template<typename T> T&& move(T&&) = delete;
This, will restrict the applicability of move to lvalues. For rvalues
we simply don't need 'move' because the only purpose of move is to
return an rvalue. The question is: Is there any drawback in having
'move' work on lvalues only?
In generic code you might not know whether the thing is an rvalue or an
lvalue, and yet you might know that moving from it is safe. For
example, if you do
T x = move(*p);
*p could turn out to be a proxy reference.
Disclaimer: I'm going to describe a *hypothetical* language feature
that solves these kinds of "dangling reference" problems. This is not
a proposal for C++0x.
I was thinking about a way to save the information that a certain
reference references a local temporary object. Example:
string&& operator+(string&& a, string const& b) {
a += b; return a;
}
string && a = string("hello") + string("world");
'a' is initialized to refer to the temporary object string("hello")
which has been altered by operator+. But extenting the object's life-
time is made impossible because the compiler doesn't know what
reference operator+ will be returning unless it inspects the
function's body.
That's why you write the above as:
string operator+(string&& a, string const& b) {
a += b; return a;
}
Suppose, we have a way of declaring that a function
returns a reference to one of the given argument references:
string&& operator+(string&& a : return, string const& b);
In this case the compiler would know exactly what reference is
returned by the function: it's a reference to the local temporary
object string("hello"). This is kown at compile-time.
Nifty. This reminds me of some of the call policies I implemented in
Boost.Python that help the library with lifetime management.
The function body would be ill-formed if the return statement doesn't
match the declaration's promise. So, the life-time extension rule we
have in C+ +98 can be applied to this object to avoid danling
references. A corresponding move() could look like this:
template<RvalueOf T> RvalueOf<T>::type move(T&& x : return)
{ return x; // returning anything else would be ill-formed }
which keeps the following line
A&& aref = move(A()); // compiler knows what 'aref' will be ref'ing
well-formed AND safe as it can apply the life-time extension rule. For
non-static member functions that contain "return *this;" the
declaration could be
class A {
// ...
A& operator+=(A const& x) : return;
};
A& A::operator+=(A const& x) : return
{
member += x.member;
return *this; // returning anything else would be ill-formed
}
This feature would reduce the danger of dangling references and make
other optimizations possible. For example:
- reference doesn't need to be implemented via pointer (we already
know the function's answer)
- allows safe manipulation and recycling of temporary objects
- renders every function of the form T&& f(T&& : return);
automatically safe with respect to object life-times.
Especially in the presence of rvalue references the ability to express
that a function always returns a reference to a specific reference-
parameter seems like a good complement to the life-time extension
rule.
Opinions?
I like it! Write a proposal!
--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]