Boost logo

Boost :

Subject: Re: [boost] Move semantics for std::string?
From: Dan Ivy (danivy.mail_at_[hidden])
Date: 2012-02-17 12:16:42


On Fri, Feb 17, 2012 at 1:30 AM, Jeffrey Lee Hellrung, Jr.
<jeffrey.hellrung_at_[hidden]> wrote:
> On Thu, Feb 16, 2012 at 3:06 PM, Robert Dailey <rcdailey_at_[hidden]> wrote:
>
>> On Thu, Feb 16, 2012 at 5:01 PM, Jeffrey Lee Hellrung, Jr. <
>> jeffrey.hellrung_at_[hidden]> wrote:
>>
>> > On Thu, Feb 16, 2012 at 2:40 PM, Robert Dailey <rcdailey_at_[hidden]>
>> wrote:
>> >
>> > > I'm using C++03 and would love some way to apply move semantics to a
>> > > std::string. Can boost facilitate this in some way without using smart
>> > > pointers? Consider an example like below (This is a contrived example,
>> so
>> > > assume NRVO does not apply):
>> > >
>> > > std::string GetInformation( int someNumber )
>> > > {
>> > >  // We use 'someNumber' to look up a string
>> > >  std::string myValue( "hello world" ); // Create the string here
>> > >  return myValue;
>> > > }
>> > >
>> > > Above, the return value would result in a copy, I'd like to move it
>> > > instead.
>> > >
>> >
>> > Well I think you can always make NRVO apply if you're always returning
>> the
>> > same variable, which is always possible: just swap what you would
>> otherwise
>> > return into that common variable.
>> >
>> > In general, though, no, I don't think you can cleanly introduce
>> (emulated)
>> > move semantics non-intrusively in C++03.
>>
>>
>> Just to be clear, what "common variable" are you referring to?
>>
>> Thanks for your answers.
>>
>
> std::string foo()
> {
>    std::string result;
>    /*...*/
>        // would like to "return x;", but instead...
>        result.swap(x);
>        return result;
>    /*...*/
>        // would like to "return y;", but instead...
>        result.swap(y);
>        return result;
> }
>
> - Jeff
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Or, if you're willing to count on your compiler's brains, you could
avoid the common variable:

template <typename T>
inline T swapped(T& x)
{
    T res;
    swap(x, res);
    return res;
}

string f()
{
    [...]
    // res.swap(x);
    // return res;
    return swapped(x);
}

Note that in either case, this only avoids the copy from the
return-statement expression to the return-value. What happens with the
returned string-temporary in the context of the caller is a different
issue. If you use it to construct another string, RVO will usually
kick in. However, anything else is likely to introduce a superfluous
copy, or something similiar. For example, assigning it to a string,
passing it to a function taking a 'const string&', and so on...

There has been a discussion not so long ago about rvalue emulation in
C++03, which seems to have faded away. I proposed a method there for
non-intrusive rvalue-ref emulation, with an example of how it can be
used to avoid excessive temporaries for string concatenation.
Depending on what you're actually trying to acheive, you might find
this interesting:
[http://lists.boost.org/Archives/boost/2012/02/190102.php]

--
Dan

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk