[Thread] Can't compile package_task code with 1.54

Hi, I just tried to compile my 1.52- based code with 1.54 beta and run into package_task compilation issue. In 1.52 I was using BOOST_THREAD_VERSION=3 define but with 1.54 I complied with =4. Test program: #define BOOST_THREAD_VERSION 4 #include <boost/thread/future.hpp> #include <boost/function.hpp> struct MyFunc { void operator()()const {} }; int main() { boost::function<void()> f; MyFunc mf; boost::packaged_task<void()> t1(f); // error 1 boost::packaged_task<void()> t2(mf); // error 2 } error 1 being: d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'boost::function<Signature>' to 'boost::detail::task_object<F,R> &' and error 2 similarly: d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'MyFunc' to 'boost::detail::task_object<F,R> &' (I tried with custom functor because I thought maybe error was related to boost function) Compiling with Visual Studio 2012 Update 3 Regards, Szymon Gatner

Le 01/06/13 00:56, Szymon Gatner a écrit :
Hi,
I just tried to compile my 1.52- based code with 1.54 beta and run into package_task compilation issue.
In 1.52 I was using BOOST_THREAD_VERSION=3 define but with 1.54 I complied with =4.
Test program:
#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp> #include <boost/function.hpp>
struct MyFunc { void operator()()const {} };
int main() { boost::function<void()> f; MyFunc mf;
boost::packaged_task<void()> t1(f); // error 1 boost::packaged_task<void()> t2(mf); // error 2 }
error 1 being:
d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'boost::function<Signature>' to 'boost::detail::task_object<F,R> &'
and error 2 similarly:
d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'MyFunc' to 'boost::detail::task_object<F,R> &'
(I tried with custom functor because I thought maybe error was related to boost function)
Compiling with Visual Studio 2012 Update 3
Hi, this is related to https://svn.boost.org/trac/boost/ticket/8596 which is fixed now, but maybe it doesn't works for you. Note that the trunk regression test since revision 84414 run with this compiler pass ( libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp) <https://svn.boost.org/trac/boost/browser/branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp?rev=84468> http://www.boost.org/development/tests/trunk/developer/thread.html. Unfortunately not a single msvc tester has run after revision 84468 on release branch. I have no the possibility to reproduce it now. Please could you send the whole log? (privately if you prefer? Or via a ticket? Best, Vicente

Le 01/06/13 07:30, Vicente J. Botet Escriba a écrit :
Le 01/06/13 00:56, Szymon Gatner a écrit :
Hi,
I just tried to compile my 1.52- based code with 1.54 beta and run into package_task compilation issue.
In 1.52 I was using BOOST_THREAD_VERSION=3 define but with 1.54 I complied with =4.
Test program:
#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp> #include <boost/function.hpp>
struct MyFunc { void operator()()const {} };
int main() { boost::function<void()> f; MyFunc mf;
boost::packaged_task<void()> t1(f); // error 1 boost::packaged_task<void()> t2(mf); // error 2 }
error 1 being:
d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'boost::function<Signature>' to 'boost::detail::task_object<F,R> &'
and error 2 similarly:
d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2848): error C2664: 'boost::detail::task_object<F,R>::task_object(boost::detail::task_object<F,R> &)' : cannot convert parameter 1 from 'MyFunc' to 'boost::detail::task_object<F,R> &'
(I tried with custom functor because I thought maybe error was related to boost function)
Compiling with Visual Studio 2012 Update 3
Hi,
this is related to https://svn.boost.org/trac/boost/ticket/8596 which is fixed now, but maybe it doesn't works for you. Note that the trunk regression test since revision 84414 run with this compiler pass ( libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp) <https://svn.boost.org/trac/boost/browser/branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp?rev=84468> http://www.boost.org/development/tests/trunk/developer/thread.html.
Unfortunately not a single msvc tester has run after revision 84468 on release branch.
I have no the possibility to reproduce it now. Please could you send the whole log? (privately if you prefer? Or via a ticket?
I have found the error. My tests don't test for packaged_task<void()>. The following patch should fix the issue (see attached file) Please could you apply it a tell me if it fix with your compiler? Best, Vicente svn diff future.hpp Index: future.hpp =================================================================== --- future.hpp (revision 84547) +++ future.hpp (working copy) @@ -2362,18 +2362,12 @@ task_object(task_object&); public: F f; -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - task_object(BOOST_THREAD_RV_REF(F) f_): - f(boost::forward<F>(f_)) - {} -#else task_object(F const& f_): f(f_) {} task_object(BOOST_THREAD_RV_REF(F) f_): - f(boost::move(f_)) // TODO forward + f(boost::move(f_)) {} -#endif #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args) @@ -2616,18 +2610,12 @@ task_object(task_object&); public: F f; -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - task_object(BOOST_THREAD_RV_REF(F) f_): - f(boost::forward<F>(f_)) - {} -#else task_object(F const& f_): f(f_) {} task_object(BOOST_THREAD_RV_REF(F) f_): - f(boost::move(f_)) // TODO forward + f(boost::move(f_)) {} -#endif #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)

Hi Vincente,
I have found the error. My tests don't test for packaged_task<void()>.
The following patch should fix the issue (see attached file)
Please could you apply it a tell me if it fix with your compiler?
I am happy to confirm the fix, really appreciate so quick response from you. To clarify: I was using boost_1_54_0_beta1_rc1.7z from beta announcement. Btw: I am using a workaround for packaged_task to be able store it in std/boost::function: typedef boost::packaged_task<Ret()> Task; typedef boost::shared_ptr<Task> TaskPtr; TaskP task(new Task(f)); addTask(boost::bind(&Task::operator (), task)); where: void addTask(boost::function<void()> task); not a problem of course but with 1.54 beta I was still not able to just move packaged_task to function directly: boost::packaged_task<void()> t1; boost::function<void()> f2(boost::move(t1)); gives: Error 1 error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>' d:\devel\boost_1_54_0_beta1\boost\function\function_template.hpp 1070 ConsoleApplication2 same error with std::function. Is this an issue with packaged_task or a std/boost function implementations. I think boost::functions are not movable so they probably try to copy packaged_task but not sure why it also doesn't work with std::function. Thanks again for the fix, Regards, Szymon Gtaner

Le 01/06/13 12:34, Szymon Gatner a écrit :
Hi Vincente,
I have found the error. My tests don't test for packaged_task<void()>.
The following patch should fix the issue (see attached file)
Please could you apply it a tell me if it fix with your compiler?
I am happy to confirm the fix, really appreciate so quick response from you. To clarify: I was using boost_1_54_0_beta1_rc1.7z from beta announcement.
Btw: I am using a workaround for packaged_task to be able store it in std/boost::function:
typedef boost::packaged_task<Ret()> Task; typedef boost::shared_ptr<Task> TaskPtr; TaskP task(new Task(f)); addTask(boost::bind(&Task::operator (), task));
where:
void addTask(boost::function<void()> task);
not a problem of course but with 1.54 beta I was still not able to just move packaged_task to function directly:
boost::packaged_task<void()> t1;
boost::function<void()> f2(boost::move(t1));
gives:
Error1error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>'d:\devel\boost_1_54_0_beta1\boost\function\function_template.hpp1070ConsoleApplication2
same error with std::function.
Is this an issue with packaged_task or a std/boost function implementations. I think boost::functions are not movable so they probably try to copy packaged_task but not sure why it also doesn't work with std::function.
IMO boost::function doesn't supports move semantics. I will take a look at std::function. Could you post the error with std::function? Best, Vicente

2013/6/1 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
IMO boost::function doesn't supports move semantics. I will take a look at std::function. Could you post the error with std::function?
code: #define BOOST_THREAD_VERSION 4 #include <boost/thread/future.hpp> #include <functional> int main() { boost::packaged_task<void()> t1; std::function<void()> f2(boost::move(t1)); } error: 1>------ Build started: Project: ConsoleApplication2, Configuration: Debug Win32 ------ 1> main.cpp 1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(317): error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>' 1> with 1> [ 1> <unnamed-symbol>=void (void) 1> ] 1> d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2783) : see declaration of 'boost::packaged_task<<unnamed-symbol>>::packaged_task' 1> with 1> [ 1> <unnamed-symbol>=void (void) 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(404) : see reference to function template instantiation 'std::_Callable_base<_Ty,_Indirect>::_Callable_base<_Ty&>(_Ty2)' being compiled 1> with 1> [ 1> _Ty=boost::packaged_task<void (void)>, 1> _Indirect=false, 1> _Ty2=boost::packaged_task<void (void)> & 1> ] I initially though behavior was different when using boost::move() and std::move() to move t1 but boost::move actually is std::move on C++11 compiler. Hope this helps. Cheers, Simon

Le 01/06/13 13:53, Vicente J. Botet Escriba a écrit :
Le 01/06/13 12:34, Szymon Gatner a écrit :
Hi Vincente,
I have found the error. My tests don't test for packaged_task<void()>.
The following patch should fix the issue (see attached file)
Please could you apply it a tell me if it fix with your compiler?
I am happy to confirm the fix, really appreciate so quick response from you. To clarify: I was using boost_1_54_0_beta1_rc1.7z from beta announcement.
Btw: I am using a workaround for packaged_task to be able store it in std/boost::function:
typedef boost::packaged_task<Ret()> Task; typedef boost::shared_ptr<Task> TaskPtr; TaskP task(new Task(f)); addTask(boost::bind(&Task::operator (), task));
where:
void addTask(boost::function<void()> task);
not a problem of course but with 1.54 beta I was still not able to just move packaged_task to function directly:
boost::packaged_task<void()> t1;
boost::function<void()> f2(boost::move(t1));
gives:
Error1error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>'d:\devel\boost_1_54_0_beta1\boost\function\function_template.hpp1070ConsoleApplication2
same error with std::function.
Is this an issue with packaged_task or a std/boost function implementations. I think boost::functions are not movable so they probably try to copy packaged_task but not sure why it also doesn't work with std::function.
IMO boost::function doesn't supports move semantics. I will take a look at std::function. Could you post the error with std::function?
I don't find a constructor of function from a rvalue functor. From the standard: template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f); 7 Requires: F shall be *CopyConstructible*. f shall be Callable (20.10.11.2) for argument types ArgTypes and return type R. The copy constructor and destructor of A shall not throw exceptions. 8 Postconditions: !*this if any of the following hold: --- f is a NULL function pointer. --- f is a NULL pointer to member. --- F is an instance of the function class template, and !f 9 Otherwise, *this targets a copy of f initialized with std::move(f). [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer. --- end note ] 10 Throws: shall not throw exceptions when f is a function pointer or a reference_wrapper<T> for some T. Otherwise, may throw bad_alloc or any exception thrown by F's copy or move constructor. But I find an assignment template<class F> function& operator=(F&& f); 18 Effects: function(std::forward<F>(f)).swap(*this); 19 Returns: *this This seems confusing. What am I missing? Best, Vicente

2013/6/1 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> I don't find a constructor of function from a rvalue functor.
From the standard: template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f); 7 Requires: F shall be *CopyConstructible*. f shall be Callable (20.10.11.2) for argument types ArgTypes and return type R. The copy constructor and destructor of A shall not throw exceptions. 8 Postconditions: !*this if any of the following hold: — f is a NULL function pointer. — f is a NULL pointer to member. — F is an instance of the function class template, and !f 9 Otherwise, *this targets a copy of f initialized with std::move(f). [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f’s target is an object holding only a pointer or reference to an object and a member function pointer. — end note ] 10 Throws: shall not throw exceptions when f is a function pointer or a reference_wrapper<T> for some T. Otherwise, may throw bad_alloc or any exception thrown by F’s copy or move constructor.
But I find an assignment
template<class F> function& operator=(F&& f); 18 Effects: function(std::forward<F>(f)).swap(*this); 19 Returns: *this
This seems confusing. What am I missing?
I don't have a standard but this is in sync what you describe: http://en.cppreference.com/w/cpp/utility/functional/function/function http://en.cppreference.com/w/cpp/utility/functional/function/operator%3D confusing indeed. Anyway, trying to: #define BOOST_THREAD_VERSION 4 #include <boost/thread/future.hpp> #include <functional> int main() { boost::packaged_task<void()> t; std::function<void()> f2; f2 = std::move(t); } gives exactly the same compilation error: 1>------ Build started: Project: ConsoleApplication2, Configuration: Debug Win32 ------ 1> main.cpp 1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(317): error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>' 1> with 1> [ 1> <unnamed-symbol>=void (void) 1> ] 1> d:\devel\boost_1_54_0_beta1\boost\thread\future.hpp(2783) : see declaration of 'boost::packaged_task<<unnamed-symbol>>::packaged_task' 1> with 1> [ 1> <unnamed-symbol>=void (void) 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xrefwrap(404) : see reference to function template instantiation 'std::_Callable_base<_Ty,_Indirect>::_Callable_base<_Ty&>(_Ty2)' being compiled 1> with 1> [ 1> _Ty=boost::packaged_task<void (void)>, 1> _Indirect=false, 1> _Ty2=boost::packaged_task<void (void)> & 1> ] but that might as well be VC2012 bug as there is plenty :/ Regards, Simon

Le 01/06/13 15:15, Szymon Gatner a écrit :
2013/6/1 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr <mailto:vicente.botet@wanadoo.fr>>
I don't find a constructor of function from a rvalue functor.
But I find an assignment
This seems confusing. What am I missing?
I don't have a standard but this is in sync what you describe:
http://en.cppreference.com/w/cpp/utility/functional/function/function
http://en.cppreference.com/w/cpp/utility/functional/function/operator%3D
confusing indeed.
Anyway, trying to:
#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp> #include <functional>
int main() { boost::packaged_task<void()> t;
std::function<void()> f2; f2 = std::move(t); }
gives exactly the same compilation error:
I get the same kind of error for gcc-4.8.0 and clang-3.2. I suspect that either we are missing something basic or there is a issue on the standard specification and the standard library implementors have not identified it while implementing these operations. Best, Vicente

Le 01/06/13 14:38, Vicente J. Botet Escriba a écrit :
Le 01/06/13 13:53, Vicente J. Botet Escriba a écrit :
Le 01/06/13 12:34, Szymon Gatner a écrit :
Hi Vincente,
I have found the error. My tests don't test for packaged_task<void()>.
The following patch should fix the issue (see attached file)
Please could you apply it a tell me if it fix with your compiler?
I am happy to confirm the fix, really appreciate so quick response from you. To clarify: I was using boost_1_54_0_beta1_rc1.7z from beta announcement.
Btw: I am using a workaround for packaged_task to be able store it in std/boost::function:
typedef boost::packaged_task<Ret()> Task; typedef boost::shared_ptr<Task> TaskPtr; TaskP task(new Task(f)); addTask(boost::bind(&Task::operator (), task));
where:
void addTask(boost::function<void()> task);
not a problem of course but with 1.54 beta I was still not able to just move packaged_task to function directly:
boost::packaged_task<void()> t1;
boost::function<void()> f2(boost::move(t1));
gives:
Error1error C2248: 'boost::packaged_task<<unnamed-symbol>>::packaged_task' : cannot access private member declared in class 'boost::packaged_task<<unnamed-symbol>>'d:\devel\boost_1_54_0_beta1\boost\function\function_template.hpp1070ConsoleApplication2
same error with std::function.
Is this an issue with packaged_task or a std/boost function implementations. I think boost::functions are not movable so they probably try to copy packaged_task but not sure why it also doesn't work with std::function.
IMO boost::function doesn't supports move semantics. I will take a look at std::function. Could you post the error with std::function?
I don't find a constructor of function from a rvalue functor.
From the standard: template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f); 7 Requires: F shall be *CopyConstructible*. f shall be Callable (20.10.11.2) for argument types ArgTypes and return type R. The copy constructor and destructor of A shall not throw exceptions. 8 Postconditions: !*this if any of the following hold: --- f is a NULL function pointer. --- f is a NULL pointer to member. --- F is an instance of the function class template, and !f 9 Otherwise, *this targets a copy of f initialized with std::move(f). [Note: Implementations are encouraged to avoid the use of dynamically allocated memory for small callable objects, for example, where f's target is an object holding only a pointer or reference to an object and a member function pointer. --- end note ] 10 Throws: shall not throw exceptions when f is a function pointer or a reference_wrapper<T> for some T. Otherwise, may throw bad_alloc or any exception thrown by F's copy or move constructor.
But I find an assignment
template<class F> function& operator=(F&& f); 18 Effects: function(std::forward<F>(f)).swap(*this); 19 Returns: *this
This seems confusing. What am I missing? I've a clear answer from Howard. See below.
Le 01/06/13 18:29, Howard Hinnant a écrit :
The reason F has to be CopyConstructible is not because of the signatures of the constructor and assignment operator. Both could be F, or F&&, and we appear to have split the difference. :-)
The reason F has to be CopyConstructible is because of function's copy constructor, and because F is type-erased inside of function. Because F is type-erased, when function is copied, it must copy F using a virtual function call (or via a function pointer). And because F's copy constructor must be called via a virtual function, F's copy constructor is instantiated whether or not function's copy constructor is instantiated. And that is why F must be CopyConstructible.
If F was not type-erased inside of function, F would not have to be CopyConstructible until actually copied.

2013/6/1 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
I've a clear answer from Howard. See below.
Le 01/06/13 18:29, Howard Hinnant a écrit :
The reason F has to be CopyConstructible is not because of the signatures of the constructor and assignment operator. Both could be F, or F&&, and we appear to have split the difference. :-)
The reason F has to be CopyConstructible is because of function's copy constructor, and because F is type-erased inside of function. Because F is type-erased, when function is copied, it must copy F using a virtual function call (or via a function pointer). And because F's copy constructor must be called via a virtual function, F's copy constructor is instantiated whether or not function's copy constructor is instantiated. And that is why F must be CopyConstructible.
If F was not type-erased inside of function, F would not have to be CopyConstructible until actually copied.
Ah, perfectly clear now. Awesome of you to to share the info. Regards, Simon
participants (2)
-
Szymon Gatner
-
Vicente J. Botet Escriba