Boost logo

Boost Users :

Subject: Re: [Boost-users] [move] differences between results in C++03 and C++11 modes
From: Lee Clagett (forum_at_[hidden])
Date: 2014-02-11 20:34:46


On Tue, Feb 11, 2014 at 9:14 AM, Krzysztof Czainski <1czajnik_at_[hidden]>wrote:

> 2014-02-11 14:11 GMT+01:00 Ion Gaztañaga <igaztanaga_at_[hidden]>:
>
>> El 11/02/2014 8:55, Adam Romanek escribió:
>>
>> Hi!
>>>
>>> Some time ago I encountered a problem with assigning the return value of
>>> boost::move() to a non-const reference in C++11 mode, but not in C++03
>>> mode. See [1] for a StackOverflow question that I created for this
>>> issue. It contains all the details so for brevity I won't repeat them
>>> here. Could anyone explain this issue? Is this a limitation of C++03
>>> emulation or a defect in the implementation?
>>>
>>
>> Yes, it's a limitation of boost move. When called with the emulation code
>> boost::move() returns a type rv<T> & that is convertible to T (and that is
>> the key point to implement emulated move semantics). However in C++11 you
>> return a T&& (unnamed rvalue reference) which is not assignable to T &.
>>
>> In your case, as R is std::ostream &, the emulation return
>> rv<std::ostrean> (convertible to std::ostream &) and the C++11 version
>> returns std::ostream &&, which is not convertible to std::ostream &.
>>
>> I guess we could add a new macro to boost move for return types. In
>> emulated mode, it moves the return value, In C++11 mode it only return the
>> value (If RVO can't be applied the compiler will do an implicit move).
>> Something like:
>>
>> //return boost::move(r) in emulation
>> //return r in C++11
>> return BOOST_MOVE_RET(r);
>>
> +1
> I've written and use such a macro myself.
> Regards,
> Kris
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>

I recently wanted to write such a macro too. Objects marked with
BOOST_MOVABLE_BUT_NOT_COPYABLE have to be returned with "return
boost::move(temp)" or C++03 compilers try to use the private
copy-constructor on temp. Doing a boost::move return prevents NRVO in
C++03, and C++11 (according to the language purists and gcc 4.7.3). This
macro would at least provide NRVO capabilities in C++11. I think C++03
support for NRVO in this situation is foolish; boost::move would have to
invoke a private copy-constructor on the user type and hope the compiler
didn't generate a function call to it. The documentation doesn't list these
limitations AFAIK.

Lee



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net