Le 09/04/12 20:06, Jeffrey Lee Hellrung, Jr. a écrit :
On Mon, Apr 9, 2012 at 10:41 AM, Vicente J. Botet Escriba
mailto:vicente.botet@wanadoo.fr> wrote:
Le 08/04/12 17:18, Jeffrey Lee Hellrung, Jr. a écrit :
On Sun, Apr 8, 2012 at 5:46 AM, Vicente J. Botet Escriba
mailto:vicente.botet@wanadoo.fr> wrote:
After the commit some error have appeared on the regression test
(see below). It seems that the rvalue reference semantic has
changed a lot for gcc. I will try to use the last design for this
compiler version. Then I'll see what needs to be done for other
compilers as soon as results appear on the regression tests page.
TBH, I wasn't really sure exactly what problem you were trying to
address with that patch, and how it addressed that :/ Care to recap?
Note that I think we have 2 threads here on Boost.Thread, one
regarding VS 2010 and one regarding Sun. I might be getting them confused.
Hi,
Sorry for all this noise.
I'm replaying to the error signaled on this thread and it concerns VS
2010 (not Sun) and concerns also other compilers (in particular I tested
the example below with clang 3.0, gcc-4.6.2,4.7.0)
The signaled error was
E:\boost_1_49\boost/thread/future.hpp(1251): error C2535:
'boost::detail::task_object::task_object(F)' : member function
already defined or declared
with
[
R=size_t,
F=std::tr1::_Bind,const char *>> &
]
E:\boost_1_49\boost/thread/future.hpp(1247) : see declaration
of 'boost::detail::task_object::task_object'
with
[
R=size_t,
F=std::tr1::_Bind,const char *>> &
]
The concerned code is
template
struct task_object:
task_base<R>
{
F f;
task_object(F const& f_):
f(f_)
{}
task_object(F&& f_):
f(f_)
{}
template<typename R>
class packaged_task
{
template <class F>
explicit packaged_task(F const& f):
task(new detail::task_object(f)),future_obtained(false)
{}
explicit packaged_task(R(*f)()):
task(new
detail::task_object(f)),future_obtained(false)
{}
template <class F>
explicit packaged_task(F&& f):
task(new
detail::task_object(f)),future_obtained(false) // *** 1
{}
I think the error comes from the following line in the example (see ***2
below)
async_func_pt<RetType>* p= new async_func_pt<RetType>
(boost::packaged_task<RetType>(f));
that should forward the reference while passing f.
async_func_pt<RetType>* p= new async_func_pt<RetType>
(boost::packaged_task<RetType>(std::forward<F>(f)));
because otherwise I believe the deduced template type is F&. Am I right?
When F& was given to the constructor of packaged_task it instantiated
task_object
As the same error were in the the Boost.Thread code in (1) above. The
use of forward solves the issue
task(new
detail::task_object(boost::forward<F>(f))),future_obtained(false)
// *** 1
So the instantiated constructors were
task_object( const F& & f_):
f(f_)
{}
task_object(F& && f_):
f(f_)
{}
which produced the ambiguity.
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?
The test futures/packaged_task/alloc_ctor_pass.cpp gives this context.
Thanks for your patience and perseverance.
Best,
Vicente
P.S. I have committed the example as test_ml.cpp with some modifications.
I have rolled back the code adding the forward calls and I'll commit it
in trunk as sonn as the whole regression works on all the compiler I can
test.
======================================================
#include "boost/test/unit_test.hpp"
#include "boost/thread/future.hpp"
#include "boost/utility/result_of.hpp"
#include <functional>
struct async_func {
virtual ~async_func() { }
virtual void run() =0;
};
template <typename Ret>
class async_func_pt : public async_func {
boost::packaged_task<Ret> f;
public:
void run() override { f(); }
async_func_pt (boost::packaged_task<Ret>&& f) : f(std::move(f)) {}
~async_func_pt() { }
boost::unique_future<Ret> get_future() { return f.get_future(); }
};
void async_core (async_func* p);
template <typename F>
boost::unique_future::type>
async (F&& f)
{
typedef typename boost::result_of< F() >::type RetType;
async_func_pt<RetType>* p= new async_func_pt<RetType>
(boost::packaged_task<RetType>(f)); // ***2
boost::unique_future<RetType> future_result= p->get_future();
async_core (p);
return std::move(future_result);
}
template
boost::unique_future::type>
async (F&& f, A1&& a1)
{
// This should be all it needs. But get a funny error deep inside Boost.
// problem overloading with && ?
return async (std::tr1::bind(f,a1));
}
BOOST_AUTO_TEST_SUITE(thread_pool_tests)
int calculate_the_answer_to_life_the_universe_and_everything()
{
return 42;
}
size_t foo (const std::string& s)
{
return s.size();
}
BOOST_AUTO_TEST_CASE( async_test )
{
// this one works
// most fundimental form:
boost::unique_future<int> fi= async
(&calculate_the_answer_to_life_the_universe_and_everything);
int i= fi.get();
BOOST_CHECK_EQUAL (i, 42);
// This one chokes at compile time
boost::unique_future fut_1= async (&foo, "Life");
BOOST_CHECK_EQUAL (fut_1.get(), 4);
}
BOOST_AUTO_TEST_SUITE_END()