title: C++17 structured binding that also includes an existing variable
body: <p><a href="https://stackoverflow.com/a/40241520/1424877">This SO answer</a> lists some shortcomings of C++17 decomposition declarations (the feature formerly known as "structured binding"). For example, you can't give explicit types to the new variables, and so on. But one big shortcoming I'm running into isn't mentioned there, so I wonder if there's a known workaround that I'm just not thinking of.</p>
  
  <p>Consider <a href="http://melpon.org/wandbox/permlink/f2OJ6CKswPsjh19I" rel="noreferrer">this JSON-parsing code</a> (which may contain other bugs; please ignore them for the purposes of this question):</p>
  
  <pre><code>using Value = std::any;
  using String = std::string;
  using Object = std::map&lt;String, Value&gt;;
  
  std::pair&lt;String, const char *&gt; load_string(const char *p, const char *end);
  std::pair&lt;Value, const char *&gt; load_value(const char *p, const char *end);
  const char *skip_spaces(const char *p, const char *end);
  
  std::pair&lt;Object, const char *&gt; load_object(const char *p, const char *end)
  {
      p = skip_spaces(p, end);
      if (p == end || *p++ != '{') throw ParseError("Expected {");
      p = skip_spaces(p, end);
      Object result;
      if (p == end &amp;&amp; *p == '}') {
          // the object has no key-value pairs at all
      } else {
          while (true) {
              auto [key, p] = load_string(p, end);
              p = skip_spaces(p, end);
              if (p == end || *p++ != ':') throw ParseError("Expected :");
              auto [value, p] = load_value(p, end);
              result.insert_or_assign(std::move(key), std::move(value));
              p = skip_spaces(p, end);
              if (p == end) throw ParseError("Expected , or }");
              if (*p == '}') break;
              if (*p++ != ',') throw ParseError("Expected , or }");
          }
      }
      return {result, p+1};
  }
  </code></pre>
  
  <p>This would work great, except that the lines starting <code>auto [key, p] =</code> and <code>auto [value, p] =</code> are invalid! The variable <code>p</code> has already been declared. I'm trying to assign <code>p</code> a new <em>value</em>, but I don't want to create a whole new <em>local variable</em>.</p>
  
  <p>I would prefer not to use <code>std::tie(key, p) =</code>, because that requires me to give a declaration for <code>key</code> before the assignment. This is the familiar old objection to <code>std::tie</code>. Which I could have sworn was the reason structured binding was introduced into the language!</p>
  
  <p>So is there any workaround — any nice clean way of writing the combination construct-<code>key</code>-in-place-and-also-assign-to-<code>p</code> that expresses my <em>intention</em>?</p>
  
  <p>It's strange how I never missed this feature before, but as soon as you give me structured binding to play with, the first thing I try doesn't work. :(</p>