title: Why does auto return type change the overload resolution?
body: <p>Thanks to <code>decltype</code> as a return type, C++11 made it extremely easy to introduce decorators.  For instance, consider this class:</p>
  
  <pre><code>struct base
  {
    void fun(unsigned) {}
  };
  </code></pre>
  
  <p>I want to decorate it with additional features, and since I will do that several times with different kinds of decorations, I first introduce a <code>decorator</code> class that simply forwards everything to <code>base</code>.  In the real code, this is done via <code>std::shared_ptr</code> so that I can remove decorations and recover the "naked" object, and everything is templated.</p>
  
  <pre><code>#include &lt;utility&gt; // std::forward
  struct decorator
  {
    base b;
  
    template &lt;typename... Args&gt;
    auto
    fun(Args&amp;&amp;... args)
      -&gt; decltype(b.fun(std::forward&lt;Args&gt;(args)...))
    {
      return b.fun(std::forward&lt;Args&gt;(args)...);
    }
  };
  </code></pre>
  
  <p>Perfect forwarding and <code>decltype</code> are just wonderful.  In the real code, I actually use a macro that just needs the name of the function, all the rest is boilerplate.</p>
  
  <p>And then, I can introduce a <code>derived</code> class that adds features to my object (<code>derived</code> is improper, agreed, but it helps understanding that <code>derived</code> is-a-kind of <code>base</code>, albeit not via inheritance).</p>
  
  <pre><code>struct foo_t {};
  struct derived : decorator
  {
    using decorator::fun; // I want "native" fun, and decorated fun.
    void fun(const foo_t&amp;) {}
  };
  
  int main()
  {
    derived d;
    d.fun(foo_t{});
  }
  </code></pre>
  
  <p>Then C++14 came, with return type deduction, which allows to write things in a simpler way: remove the <code>decltype</code> part of the forwarding function:</p>
  
  <pre><code>struct decorator
  {
    base b;
  
    template &lt;typename... Args&gt;
    auto
    fun(Args&amp;&amp;... args)
    {
      return b.fun(std::forward&lt;Args&gt;(args)...);
    }
  };
  </code></pre>
  
  <p>And <em>then</em> it breaks.  Yes, at least according to both GCC and Clang, this:</p>
  
  <pre><code>  template &lt;typename... Args&gt;
    auto
    fun(Args&amp;&amp;... args)
      -&gt; decltype(b.fun(std::forward&lt;Args&gt;(args)...))
    {
      return b.fun(std::forward&lt;Args&gt;(args)...);
    }
  };
  </code></pre>
  
  <p>is not equivalent to this (and the issue is not <code>auto</code> vs. <code>decltype(auto)</code>):</p>
  
  <pre><code>  template &lt;typename... Args&gt;
    auto
    fun(Args&amp;&amp;... args)
    {
      return b.fun(std::forward&lt;Args&gt;(args)...);
    }
  };
  </code></pre>
  
  <p>The overload resolution seems to be completely different and it ends like this:</p>
  
  <pre><code>clang++-mp-3.5 -std=c++1y main.cc
  main.cc:19:18: error: no viable conversion from 'foo_t' to 'unsigned int'
      return b.fun(std::forward&lt;Args&gt;(args)...);
                   ^~~~~~~~~~~~~~~~~~~~~~~~
  main.cc:32:5: note: in instantiation of function template specialization
        'decorator::fun&lt;foo_t&gt;' requested here
    d.fun(foo_t{});
      ^
  main.cc:7:20: note: passing argument to parameter here
    void fun(unsigned) {}
                     ^
  </code></pre>
  
  <p>I understand the failure: my call (<code>d.fun(foo_t{})</code>) does not match perfectly with the signature of <code>derived::fun</code>, which takes a <code>const foo_t&amp;</code>, so the very eager <code>decorator::fun</code> kicks in (we know how <code>Args&amp;&amp;...</code> is extremely impatient to bind to anything that does not match perfectly).  So it forwards this to <code>base::fun</code> which can't deal with <code>foo_t</code>.</p>
  
  <p>If I change <code>derived::fun</code> to take a <code>foo_t</code> instead of <code>const foo_t&amp;</code>, then it works as expected, which shows that indeed here the problem is that there is a competition between <code>derived::fun</code> and <code>decorator::fun</code>.</p>
  
  <p>However why the heck does this show with return-type deduction???  And more precisely <em>why</em> was this behavior chosen by the committee?</p>
  
  <p>To make things easier, on Coliru:</p>
  
  <ul>
  <li><a href="http://coliru.stacked-crooked.com/a/af2d798dd93ee4f5">the version with <code>decltype</code> that works</a></li>
  <li><a href="http://coliru.stacked-crooked.com/a/4c627ff3d74ff174">the version with type deduction that fails</a></li>
  </ul>
  
  <p>Thanks!</p>