On Mon, Apr 9, 2012 at 3:14 PM, Vicente J. Botet Escriba
mailto:vicente.botet@wanadoo.fr> 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. I have a
Le 10/04/12 01:24, Jeffrey Lee Hellrung, Jr. a écrit :
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(f)),future_obtained(false)
{}
seems necessary because otherwise the task_object is instantiated with
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
#include
#include
+#include
#include
#include
#include
@@ -1807,16 +1808,16 @@
explicit packaged_task(R(*f)()):
task(new
detail::task_object(f)),future_obtained(false)
{}
- template <class F>
- explicit packaged_task(F const& f):
- task(new detail::task_object(f)),future_obtained(false)
- {}
#ifndef BOOST_NO_RVALUE_REFERENCES
template <class F>
explicit packaged_task(F&& f):
- task(new
detail::task_object(boost::forward<F>(f))),future_obtained(false)
+ task(new detail::task_object(boost::forward<F>(f))),future_obtained(false)
{}
#else
+ template <class F>
+ explicit packaged_task(F const& f):
+ task(new detail::task_object(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
- 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 >::other A2;
+ typedef typename remove_reference<F>::type FR;
+ typedef typename Allocator::template
rebind >::other A2;
A2 a2(a);
typedef thread_detail::allocator_destructor<A2> D;
- task = task_ptr(::new(a2.allocate(1))
detail::task_object(f), D(a2, 1) );
- std::cout << __FILE__ ":"<<__LINE__<(boost::forward<F>(f)), D(a2, 1) );
future_obtained = false;
}
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#else
template
- 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 >::other A2;
A2 a2(a);
typedef thread_detail::allocator_destructor<A2> D;
- task = task_ptr(::new(a2.allocate(1))
detail::task_object(boost::forward<F>(f)), D(a2, 1) );
+ task = task_ptr(::new(a2.allocate(1))
detail::task_object(f), D(a2, 1) );
+ std::cout << __FILE__ ":"<<__LINE__<
packaged_task(boost::allocator_arg_t, Allocator a,
boost::rv<F>& f)