title: How to return std::lock_guard in a std::pair
body: <p>When I go to return a <code>std::lock_guard</code> in a <code>std::pair</code> from a function I get horrible errors. But when I package it in a class I have no problems (compiles and works as expected). I can't understand why. Details follow:</p>
  
  <p>I devised a small template class to enable convenient locking and unlocking of shared objects. It's not particularly innovative, but C++17 allows it to be very compact and code read/write friendly:</p>
  
  <pre><code>template &lt;typename T&gt; class Locked {
  public:
      Locked(T&amp; _object, std::mutex&amp; _mutex)
          : object(_object)
          , lock(_mutex)
      {
      }
  
      T&amp;                          object;
      std::lock_guard&lt;std::mutex&gt; lock;
  };
  
  template &lt;typename T&gt; class Lockable {
  public:
      Locked&lt;T&gt;       borrow() { return Locked(object, mutex); }
      Locked&lt;const T&gt; borrow() const { return Locked(object, mutex); }
  
  private:
      T                  object;
      mutable std::mutex mutex;
  };
  </code></pre>
  
  <p>It can be used like:</p>
  
  <pre><code>int main()
  {
      Lockable&lt;std::vector&lt;int&gt;&gt; lv;
  
      auto [vec, lock] = lv.borrow();
  
      std::cout &lt;&lt; vec.size() &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>My question is this. The <code>Locked</code> class is very thin. I thought I could use <code>std::pair</code> instead of a formal class, like so:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;mutex&gt;
  #include &lt;utility&gt;
  #include &lt;vector&gt;
  
  template &lt;typename T&gt; class Lockable {
  public:
      std::pair&lt;T&amp;, std::lock_guard&lt;std::mutex&gt;&gt;       borrow()
      { return std::pair(object, std::lock_guard&lt;std::mutex&gt;(mutex)); }
      std::pair&lt;const T&amp;, std::lock_guard&lt;std::mutex&gt;&gt; borrow() const
      { return std::pair(object, std::lock_guard&lt;std::mutex&gt;(mutex)); }
  
  private:
      T                  object;
      mutable std::mutex mutex;
  };
  
  int main()
  {
      Lockable&lt;std::vector&lt;int&gt;&gt; lv;
  
      auto [vec, lock] = lv.borrow();
  
      std::cout &lt;&lt; vec.size() &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>But this throws up horrible, hard to parse errors. I think this has to do with <code>std::lock_guard</code> not being movable, but to me, it <em>looks</em> exactly like my working code. Why does this second version not work?</p>