This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: std::packaged_task trunk problem
Jonathan Wakely <jwakely.gcc@gmail.com> writes:
| On 7 November 2011 09:51, Jonathan Wakely wrote:
>> On 7 November 2011 09:26, Lars Gullik Bjønnes wrote:
>>>
>>> This is the wrapper I ended up with. I had to remove the throw, it
>>> triggered all the time.
>>
>> What if you give PretendToBeCopyable a noexcept destructor?
>> That should ensure the container will move it rather than copy it,
>> whenever possible.
>
| And of course also make the copy constructor throw again, or you won't
| know if the nothrow destructor made any difference or not.
Making the destructor noexcept does not even compile.
Below is the example code that I am toying with now, not that the copy
constructor seems to never be called, probably sine vec never is
resized. In my larger code, the throw triggers always.
#include <iostream>
#include <future>
#include <thread>
#include <vector>
std::vector<std::function<void()>> vec;
template<typename Moveable>
struct PretendToBeCopyable
{
explicit PretendToBeCopyable(Moveable&& m) : m(std::move(m)) {}
//~PretendToBeCopyable() noexcept = default;
PretendToBeCopyable(PretendToBeCopyable&&) = default;
PretendToBeCopyable(PretendToBeCopyable& p)
: m(std::move(p.m))
{
// This would never throw in this example sin vec is never
// resized.
// throw 5;
}
void operator()() { m(); }
private:
Moveable m;
};
template<typename F>
std::future<typename std::result_of<F()>::type> spawn_task(F f)
{
typedef typename std::result_of<F()>::type result_type;
typedef std::packaged_task<result_type()> task_type;
task_type task(std::move(f));
std::future<result_type> res = task.get_future();
vec.push_back(PretendToBeCopyable<task_type>(std::move(task)));
std::thread([]()
{
auto task = std::move(vec.back());
vec.pop_back();
task();
}
).detach();
return std::move(res);
}
double get_res()
{
return 42.2;
}
int main()
{
auto f = spawn_task(get_res);
std::cout << "Res = " << f.get() << std::endl;
}