title: Why must std::visit have a single return type?
body: <p>While playing around with <code>std::variant</code> and <code>std::visit</code> the following question came up:</p>
  
  <p>Consider the following code:</p>
  
  <pre><code>using Variant = std::variant&lt;int, float, double&gt;;
  
  auto lambda = [](auto&amp;&amp; variant) {
    std::visit(
      [](auto&amp;&amp; arg) {
        using T = std::decay_t&lt;decltype(arg)&gt;;
        if constexpr (std::is_same_v&lt;T, int&gt;) {
          std::cout &lt;&lt; "int\n";
        } else if (std::is_same_v&lt;T, float&gt;) {
          std::cout &lt;&lt; "float\n";
        } else {
          std::cout &lt;&lt; "double\n";
        }
      },
    variant);
  };
  </code></pre>
  
  <p>It works fine as the following examples show:</p>
  
  <pre><code>lambda(Variant(4.5));    // double
  lambda(Variant(4.f));    // float
  lambda(Variant(4));      // int
  </code></pre>
  
  <p>Then why does the following fail:</p>
  
  <pre><code>using Variant = std::variant&lt;int, float, double&gt;;
  
  auto lambda = [](auto&amp;&amp; variant) {
    std::visit([](auto&amp;&amp; arg) { return arg; }, variant);
  };
  
  auto t = lambda(Variant(4.5));
  </code></pre>
  
  <p>due to the static assertion</p>
  
  <pre><code>static_assert failed due to requirement '__all&lt;is_same_v&lt;int
        (*)(__value_visitor&lt;(lambda at main.cc:25:7)&gt; &amp;&amp;,
        __base&lt;std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
        double&gt; &amp;), float (*)(__value_visitor&lt;(lambda at main.cc:25:7)&gt; &amp;&amp;,
        __base&lt;std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
        double&gt; &amp;)&gt;, is_same_v&lt;int (*)(__value_visitor&lt;(lambda at main.cc:25:7)&gt; &amp;&amp;,
        __base&lt;std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
        double&gt; &amp;), double (*)(__value_visitor&lt;(lambda at main.cc:25:7)&gt; &amp;&amp;,
        __base&lt;std::__1::__variant_detail::_Trait::_TriviallyAvailable, int, float,
        double&gt; &amp;)&gt; &gt;::value' "`std::visit` requires the visitor to have a single
        return type."
  </code></pre>
  
  <p><code>std::visit</code> can obviously deduce the type of <code>arg</code> as the successful example shows. Then why the requirement to have a single return type?</p>
  
  <p>Compiler is <code>Apple LLVM version 10.0.1 (clang-1001.0.46.4)</code> but <code>gcc version 8.3.0</code> fails with a similar error.</p>