Boost logo

Boost Users :

Subject: Re: [Boost-users] [Thread] 1.53 fails to compile working code
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-02-08 18:41:43


Le 09/02/13 00:13, Jeffrey Lee Hellrung, Jr. a écrit :
> On Fri, Feb 8, 2013 at 1:31 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden] <mailto:vicente.botet_at_[hidden]>> wrote:
>
> Le 08/02/13 19:01, Jeffrey Lee Hellrung, Jr. a écrit :
>> On Thu, Feb 7, 2013 at 11:46 PM, Szymon Gatner
>> <szymon.gatner_at_[hidden] <mailto:szymon.gatner_at_[hidden]>> wrote:
>>
>> 2013/2/8 Jeffrey Lee Hellrung, Jr.
>> <jeffrey.hellrung_at_[hidden] <mailto:jeffrey.hellrung_at_[hidden]>>:
>> >
>> > This looks like an error in the future_traits<T>::init
>> overload set...it's
>> > missing an overload that a T const & can bind to (in the
>> second argument).
>> >
>> > Also, I think it would be an improvement if
>> set_value_at_thread_exit was
>> > able to catch rvalues as emulated rvalue references (when
>> true rvalue
>> > references are unavailable) rather than as
>> lvalue-reference-to-const.
>> >
>>
>> Yes indeed, there is an overload resolution ambiguity.
>>
>>
>> Strictly speaking, it isn't an ambiguity that's causing the
>> compiler failure, it's that the eligible overload set is empty.
> You are right.
>>
>> I guess movable
>> / emulation stuff in Thread is more difficult to manage since it
>> maintains 2 move emulations (original one from Thread and Move).
>>
>>
>> Yes :( I can imagine the maintenance nightmare for Vicente.
> I don't know if I've missed something really relevant of
> Boost.Move, but only with this emulation I have a lot of
> difficulties as not only Boost.Thread defines Movable types, but
> it offers interfaces with functions that can be movable and that
> accept copyable/movable arguments and that can return movable types.
>>
>> Move
>> already provides BOOST_RV_REF(T) macro which is T&& on
>> compiler that
>> support it and rv<T>& when emulating and this imho is the
>> argument
>> type future_traits<T>::init() should use to disambiguate.
>>
>>
>> Ideally, but the present implementation of
>> set_value_at_thread_exit precludes init capturing by rvalue
>> reference, AFAICT.
> Jeffrey I believe the problem comes from the fact that I have
> added two overloads for set_value_at_thread_exit and the copy
> overload is instantiated when using a move-only class
>
> void set_value_at_thread_exit(const T & result_){...}
> // this instantiation with a MoveOnly class results in a compiler
> error
> void set_value_at_thread_exit(BOOST_THREAD_RV_REF(T)
> result_){...}
>
>> Is the original move emulation even still needed in Thread code.
>>
> Using Boost.Move is some kind of breaking change respect to the
> old one. I'm fully for discarding the old emulation, but I would
> like to hear what others thing.
>>
>> I think there are subtle differences, perhaps not all of which
>> have been worked out or discovered yet.
>>
>>
> I don't think the problem comes from trying to manage 2 move
> emulations, but of course I might be wrong.
>
> anyway, I will see if I can fix it or otherwise I would restraint
> the use of _at_thread_exit functions to the compilers supporting
> them completely.
>
>
> Vicente, here's some tips on how to improve the robustness of the code
> when compiling without rvalue references (i.e., C++03):
>
> If you know a function is going to receive only lvalues or *emulated*
> rvalue references, it's sufficient to use a T & parameter: [[template<
> class T > void f(T & x);]] (Just be careful you don't accidentally
> move x; you may need to wrap some uses of x as [[as_lvalue(x)]] to
> avoid that.) This is the appropriate case for functions that receive
> results of boost::forward; I think future_traits::init falls in this
> category.
>
> If a function is designed to accept both lvalues *and* rvalues *of an
> a priori known type T*, and you want to be able to capture rvalues by
> emulated rvalue reference (when appropriate), then you need have 2 cases:
> - T is not Boost.Move-enabled: 1 overload is probably sufficient (if
> you don't care about constness): [[void f(T const &);]]
> - T is Boost.Move-enabled: 2 overloads are necessary: [[void f(rv<T>
> &);]] and [[template< class U > void f(U &);]]
>
> Lastly, if a function is designed to accept both lvalues and rvalues
> of *any* type, and you want to be able to capture any rvalue by
> emulated rvalue reference when possible, you need 3 overloads, and
> even then it's not always possible (if the function return type
> depends on the parameter type, you're probably SOL). This is much more
> involved, so I won't go into detail here, as I think the issues
> relevant to this thread fall into one of the two cases above.
>
> If you want more detailed help (e.g., patches), we can take this offline.
>
>
Hi,

I have reached to make it compile, but I suspect that there is yet a
race condition as the test fail/pass randomly.

See attached the patch.

Jeffrey any help on this will be really welcome. Contact me offline if
you get something.

Thanks,
Vicente





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