Boost logo

Boost Users :

Subject: Re: [Boost-users] [Thread] Can't compile package_task code with 1.54
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-06-01 12:53:28


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.
>



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