|
Boost Users : |
Subject: Re: [Boost-users] problems with Boost.Thread on VS10
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-04-09 19:54:26
Le 10/04/12 01:24, Jeffrey Lee Hellrung, Jr. a écrit :
> On Mon, Apr 9, 2012 at 3:14 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden] <mailto:vicente.botet_at_[hidden]>> wrote:
>
>
> There are yet some problems on the Boost.Thread implementation or
> with the compilers implementation.
>
> When I want to pass functor, as in
>
> A a(5);
> boost::packaged_task<int> pt(a);
>
> the constructor used is packaged_task(F&& f) and I will expect
> packaged_task(F const& f) to be use for.
> Are my expectations correct?
>
>
> Well...no, apparently your expectations are not correct. But that's
> slightly beside the point. I think the correct fix here is to remove
> the packaged_task(F const &) overload entirely, since the
> packaged_task(F&&) overload already covers it (that's part of the
> entire design of "templated rvalue references", to capture both
> rvalues *and* lvalues). Then instantiate task_object with something
> like remove_cv< remove_reference<F>::type >::type, and use
> boost::forward<F>(f) to pass the function object down to the
> task_object constructor.
Yeah, this is the point. packaged_task(F const &) overload was not used
never, and task_object was instantiated as task_object<R,A&>. I have a
patch that seems to work (see below I have not used remove_cv yet, but I
agree it should be needed to take care of const functors).
The overload
explicit packaged_task(R(*f)()):
task(new
detail::task_object<R,R(*)()>(f)),future_obtained(false)
{}
seems necessary because otherwise the task_object is instantiated with
<R,R()> which is not what we want.
Do you have an hint on how simplify this?
>
> The test futures/packaged_task/alloc_ctor_pass.cpp gives this context.
>
> Thanks for your patience and perseverance.
>
>
> And thank you for clarifying the issue for me!
>
>
Please, could you check the patch and see if there is something that can
be improved.
Thanks for all,
Vicente
iMac-de-Vicente-Botet-Escriba:trunk viboes$ svn diff boost/thread
libs/thread
Index: boost/thread/future.hpp
===================================================================
--- boost/thread/future.hpp (revision 77870)
+++ boost/thread/future.hpp (working copy)
@@ -19,6 +19,7 @@
#include <boost/scoped_ptr.hpp>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_reference.hpp>
#include <boost/mpl/if.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
@@ -1807,16 +1808,16 @@
explicit packaged_task(R(*f)()):
task(new
detail::task_object<R,R(*)()>(f)),future_obtained(false)
{}
- template <class F>
- explicit packaged_task(F const& f):
- task(new detail::task_object<R,F>(f)),future_obtained(false)
- {}
#ifndef BOOST_NO_RVALUE_REFERENCES
template <class F>
explicit packaged_task(F&& f):
- task(new
detail::task_object<R,F>(boost::forward<F>(f))),future_obtained(false)
+ task(new detail::task_object<R,typename
remove_reference<F>::type>(boost::forward<F>(f))),future_obtained(false)
{}
#else
+ template <class F>
+ explicit packaged_task(F const& f):
+ task(new detail::task_object<R,F>(f)),future_obtained(false)
+ {}
#if defined BOOST_THREAD_USES_MOVE
template <class F>
explicit packaged_task(boost::rv<F>& f):
@@ -1831,29 +1832,30 @@
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#ifndef BOOST_NO_RVALUE_REFERENCES
template <class F, class Allocator>
- packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
+ packaged_task(boost::allocator_arg_t, Allocator a, F&& f)
{
- typedef typename Allocator::template
rebind<detail::task_object<R,F> >::other A2;
+ typedef typename remove_reference<F>::type FR;
+ typedef typename Allocator::template
rebind<detail::task_object<R,FR> >::other A2;
A2 a2(a);
typedef thread_detail::allocator_destructor<A2> D;
- task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(f), D(a2, 1) );
- std::cout << __FILE__ ":"<<__LINE__<<std::endl;
+ task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,FR>(boost::forward<F>(f)), D(a2, 1) );
future_obtained = false;
}
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#else
template <class F, class Allocator>
- packaged_task(boost::allocator_arg_t, Allocator a, F&& f)
+ packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
{
typedef typename Allocator::template
rebind<detail::task_object<R,F> >::other A2;
A2 a2(a);
typedef thread_detail::allocator_destructor<A2> D;
- task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(boost::forward<F>(f)), D(a2, 1) );
+ task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(f), D(a2, 1) );
+ std::cout << __FILE__ ":"<<__LINE__<<std::endl;
future_obtained = false;
}
-#else
#if defined BOOST_THREAD_USES_MOVE
template <class F, class Allocator>
packaged_task(boost::allocator_arg_t, Allocator a,
boost::rv<F>& f)
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