title: Why the compiler complains that std::thread arguments must be invocable after conversion to rvalues?
body: <p>Why the compiler complains if the the thread function delaration is changed to <code>void thr(std::shared_ptr&lt;Base&gt;&amp; p)</code>.Complie error:</p>
  
  <blockquote>
    <p>gcc-10.1.0/include/c++/10.1.0/thread: In instantiation of
    'std::thread::thread(_Callable&amp;&amp;, _Args&amp;&amp; ...) [with _Callable = void
    (&amp;)(std::shared_ptr&amp;); _Args = {std::shared_ptr&amp;};
     = void]':
    gcc-10.1.0/include/c++/10.1.0/thread:136:44: error: static assertion
    failed: std::thread arguments must be invocable after conversion to
    rvalues</p>
    
    <p>136 |           typename decay&lt;_Args>::type...>::value,</p>
  </blockquote>
  
  <p>Can someone explain me, step by step.</p>
  
  <p>I would be grateful for any hint on this question.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;memory&gt;
  #include &lt;thread&gt;
  #include &lt;chrono&gt;
  #include &lt;mutex&gt;
  
  struct Base
  {
      Base() { std::cout &lt;&lt; "  Base::Base()\n"; }
      // Note: non-virtual destructor is OK here
      ~Base() { std::cout &lt;&lt; "  Base::~Base()\n"; }
  };
  
  struct Derived: public Base
  {
      Derived() { std::cout &lt;&lt; "  Derived::Derived()\n"; }
      ~Derived() { std::cout &lt;&lt; "  Derived::~Derived()\n"; }
  };
  
  void thr(std::shared_ptr&lt;Base&gt; p)
  {
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::shared_ptr&lt;Base&gt; lp = p; // thread-safe, even though the
                                    // shared use_count is incremented
      {
          static std::mutex io_mutex;
          std::lock_guard&lt;std::mutex&gt; lk(io_mutex);
          std::cout &lt;&lt; "local pointer in a thread:\n"
                    &lt;&lt; "  lp.get() = " &lt;&lt; lp.get()
                    &lt;&lt; ", lp.use_count() = " &lt;&lt; lp.use_count() &lt;&lt; '\n';
      }
  }
  
  int main()
  {
      std::shared_ptr&lt;Base&gt; p = std::make_shared&lt;Derived&gt;();
  
      std::cout &lt;&lt; "Created a shared Derived (as a pointer to Base)\n"
                &lt;&lt; "  p.get() = " &lt;&lt; p.get()
                &lt;&lt; ", p.use_count() = " &lt;&lt; p.use_count() &lt;&lt; '\n';
      std::thread t1(thr, p), t2(thr, p), t3(thr, p);
      p.reset(); // release ownership from main
      std::cout &lt;&lt; "Shared ownership between 3 threads and released\n"
                &lt;&lt; "ownership from main:\n"
                &lt;&lt; "  p.get() = " &lt;&lt; p.get()
                &lt;&lt; ", p.use_count() = " &lt;&lt; p.use_count() &lt;&lt; '\n';
      t1.join(); t2.join(); t3.join();
  
      std::cout &lt;&lt; "after joining the threads\n" &lt;&lt;
       "  p.get() = " &lt;&lt; p.get() &lt;&lt; ", p.use_count() " &lt;&lt;p.use_count() &lt;&lt; std::endl;
      std::cout &lt;&lt; "All threads completed, the last one deleted Derived\n";
  }
  </code></pre>
  
  <p>The outputs:</p>
  
  <pre><code>Base::Base()
    Derived::Derived()
  Created a shared Derived (as a pointer to Base)
    p.get() = 0x57be80, p.use_count() = 1
  Shared ownership between 3 threads and released
  ownership from main:
    p.get() = 0, p.use_count() = 0
  local pointer in a thread:
    lp.get() = 0x57be80, lp.use_count() = 4  
  local pointer in a thread:
    lp.get() = 0x57be80, lp.use_count() = 3
  local pointer in a thread:
    lp.get() = 0x57be80, lp.use_count() = 2
    Derived::~Derived()
    Base::~Base()
  after joining the threads
    p.get() = 0, p.use_count() 0
  All threads completed, the last one deleted Derived
  </code></pre>