title: How std::packaged_task works
body: <p>I am analysing the following code snippet and am trying to understand it in detail:</p>
  
  <pre><code>template&lt;typename FUNCTION, typename... ARGUMENTS&gt;
  auto ThreadPool::add( FUNCTION&amp;&amp; Function, ARGUMENTS&amp;&amp;... Arguments ) -&gt; std::future&lt;typename std::result_of&lt;FUNCTION(ARGUMENTS...)&gt;::type&gt;
  {
      using PackedTask = std::packaged_task&lt;typename std::result_of&lt;FUNCTION(ARGUMENTS...)&gt;::type()&gt;;
  
      auto task = std::make_shared&lt;PackedTask&gt;(std::bind(std::forward&lt;FUNCTION&gt;(Function), std::forward&lt;ARGUMENTS&gt;(Arguments)...));
  
      // get the future to return later
      auto ret = task-&gt;get_future();
  
      {
          std::lock_guard&lt;std::mutex&gt; lock{jobsMutex};
          jobs.emplace([task]() { (*task)(); });
      }
  
      // let a waiting thread know there is an available job
      jobsAvailable.notify_one();
  
      return ret;
  }
  </code></pre>
  
  <p>I have few questions regarding the <code>std::packaged_task</code>. </p>
  
  <p>As you can see in the <code>add(...)</code> method body, the instance of <code>std::packaged_task</code> - <code>task</code> is local variable which scope ends with the end of the method execution. The return value <code>ret</code> of <code>std::future</code> type is returned by copy. The value of <code>ret</code> is given out of the <code>task</code> (which is local). So once the method execution is finished, the <code>task</code> goes out of scope and so <strong>I expect</strong> the connected std::future instance being returned becomes invalid, is my understanding correct?</p>
  
  <p>During the execution of the method the task method to be executed in a thread is emplaced into <code>std::queue&lt;Job&gt; jobs</code>. Why is only the pointer to <code>operator()</code> of <code>std::packaged_task</code> which holds the reference to the <code>Function</code> given as method argument held in the <code>std::queue</code>? I would expect to store directly the <code>std::packaged_task</code> in order to hold the reference to the instance being created...?</p>
  
  <p>Anyway, the source code snippet comes from the ThreadPool implementation which can be found here <a href="https://github.com/dabbertorres/ThreadPool" rel="noreferrer">https://github.com/dabbertorres/ThreadPool</a> and seems to be fully working. So I assume it is correct but unfortunately not completely clear to me... I would be very glad if someone could explain how the stuff works...</p>
  
  <p>Many thanks in advance to anyone willing to help. Cheers Martin</p>