This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]