I just took another look at this...
On Wed, Apr 4, 2012 at 9:26 PM, John M. Dlugosz <mpbecey7gu@snkmail.com> wrote:
I'm trying to use a packaged_task, and get an error on creation.
template<typename R,typename F>
struct task_object:
task_base<R>
{
F f;
task_object(F const& f_): // << refers to look here
f(f_)
{}
#ifndef BOOST_NO_RVALUE_REFERENCES
task_object(F&& f_): // <<<< Error here
f(f_)
{}
E:\boost_1_49\boost/thread/future.hpp(1251): error C2535: 'boost::detail::task_object<R,F>::task_object(F)' : member function already defined or declared
with
[
R=size_t,
F=std::tr1::_Bind<size_t,size_t,std::tr1::_Bind1<std::tr1::_Callable_fun<size_t (__cdecl *const )(std::string &),false>,const char *>> &
I think this is your problem: F is a (lvalue) reference. So F const & == F&& == F due to reference collapsing rules.
]
E:\boost_1_49\boost/thread/future.hpp(1247) : see declaration of 'boost::detail::task_object<R,F>::task_object'
with
[
R=size_t,
F=std::tr1::_Bind<size_t,size_t,std::tr1::_Bind1<std::tr1::_Callable_fun<size_t (__cdecl *const )(std::string &),false>,const char *>> &
]
So I'm thinking that VS10 (Microsoft Visual Studio 2010) has problems overloading the constructor with (T const&) and (T&&) ? But shouldn't someone have noticed that long ago?
I see two ways out here. One option is to specialize task_object for reference F's. The other is to use metafunctions to choose the right parameters for the "F const &" and "F&&" constructors, respectively, e.g., use
typename add_reference< typename add_const<F>::type >::type
in place of "F const &" (or call_traits<F>::param_type; if you weren't looking to support C++03 you could also just use "F const &" as you are now); and use
struct disabler { };
typename mpl::if_c< is_reference<F>::value, disabler, F&& >::type
in place of "F&&".
HTH,
- Jeff