I am analyzing the following code fragment and trying to understand it in detail:
template<typename FUNCTION, typename... ARGUMENTS>
auto ThreadPool::add( FUNCTION&& Function, ARGUMENTS&&... Arguments ) -> std::future<typename std::result_of<FUNCTION(ARGUMENTS...)>::type>
{
using PackedTask = std::packaged_task<typename std::result_of<FUNCTION(ARGUMENTS...)>::type()>;
auto task = std::make_shared<PackedTask>(std::bind(std::forward<FUNCTION>(Function), std::forward<ARGUMENTS>(Arguments)...));
auto ret = task->get_future();
{
std::lock_guard<std::mutex> lock{jobsMutex};
jobs.emplace([task]() { (*task)(); });
}
jobsAvailable.notify_one();
return ret;
}
I have few questions regarding std::packaged_task.
As you can see in the body of the method add(...), an instance std::packaged_taskis taska local variable whose scale ends with the completion of the method. The return value of the rettype is std::futurereturned by the copy. The value retis issued from task(which is local). Thus, as soon as the execution of the method is completed, it taskgoes beyond the scope, and therefore I expect the connected connected instance of std :: future to become invalid, do I understand correctly?
, , std::queue<Job> jobs. operator() of std::packaged_task, Function, , std::queue? std::packaged_task, ...?
, ThreadPool, https://github.com/dabbertorres/ThreadPool , , . , , , , ... , - , ...
, . Cheers Martin