Le 09/02/13 00:41, Vicente J. Botet Escriba a écrit :
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@wanadoo.fr> 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@gmail.com> wrote:
2013/2/8 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>:
>
> 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.


I have made some updates to future.hpp and now the two tests work correctly. I don't know if all the modifications are absolutely needed.

Please, could you give it a try?

Thanks,
Vicente