title: How to implement try_pop() method in queue in c++?
body: <p>Below is queue example in &quot;C++ concurrency in action 2nd&quot;.
  This example is single threaded queue, which will be modified to explain thread safe.</p>
  <pre><code>template&lt;typename T&gt;
  class queue {
   private:
    struct node {
      T data;
      std::unique_ptr&lt;node&gt; next;
      node(T data_) : data(std::move(data_)) {}
    };
    std::unique_ptr&lt;node&gt; head;
    node* tail;
   public:
    queue() : tail(nullptr) {};
    queue(const queue&amp; other) = delete;
    queue&amp; operator=(const queue&amp; other) = delete;
  
    std::shared_ptr&lt;T&gt; try_pop() {
      if (!head) return std::shared_ptr&lt;T&gt;();
      std::shared_ptr&lt;T&gt; const res(std::make_shared&lt;T&gt;(std::move(head-&gt;data)));
      std::unique_ptr&lt;node&gt; const old_head = std::move(head);
      head = std::move(old_head-&gt;next);
      if(!head) tail = nullptr;
      return res;
    }
  
    void push(T new_value) {
      std::unique_ptr&lt;node&gt; p(new node(std::move(new_value)));
      node* const new_tail = p.get();
      if(tail) {
        tail-&gt;next = std::move(p);
      } else {
        head = std::move(p);
      }
      tail = new_tail;
    }
  };
  </code></pre>
  <p>I can understand this queue works fine, but the way try_pop() is implemented seems to be weird.
  Is it better way to do like below ?</p>
  <pre><code>  std::shared_ptr&lt;T&gt; try_pop() {
      if (!head) return std::shared_ptr&lt;T&gt;();
      std::shared_ptr&lt;T&gt; const res(std::make_shared&lt;T&gt;(std::move(head-&gt;data)));
  
  //    std::unique_ptr&lt;node&gt; const old_head = std::move(head);
  //    head = std::move(old_head-&gt;next);
  
      head = std::move(head-&gt;next);
  
      if(!head) tail = nullptr;
      return res;
    }
  </code></pre>
  <p>Why head should be copied to old_head on this?
  Is there any reason I missed?</p>