Re: std::packaged_task trunk problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jonathan Wakely <jwakely.gcc@xxxxxxxxx> 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;
}



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux