Overloading structs with template call operator and generic lambdas - gcc vs clang : <p>I have discovered a code snippet that compiles and works properly in <strong>clang++ 4 (and trunk)</strong> but fails to compile in <strong>g++ 7 (and trunk)</strong>. Let's assume I have the following <code>struct</code> types:</p>

<pre><code>struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
</code></pre>

<p>I want to create an <em>overload set</em> out of lambdas which handles <code>a</code> explicitly, while <code>b</code> and <code>c</code> are "caught" with a generic lambda using an <code>auto</code> parameter:</p>

<pre><code>auto ol = overload([](a x)   { x.foo(); },
                   [](auto x){ x.bar(); })
</code></pre>

<p>When I invoke <code>ol(a{})</code>:</p>

<ul>
<li><p><strong>clang++</strong> compiles and behaves as expected: <code>a</code> "matches" the first lambda, while <code>b</code> and <code>c</code> match the second one.</p></li>
<li><p><strong>g++</strong> fails to compile, with the following error:</p>

<pre><code>error: 'struct a' has no member named 'bar'
           [](auto x){ x.bar(); };
                       ~~^~~
</code></pre>

<p>It seems that the compiler tries to instantiate the second lambda even though the first one is a way better match. Hopefully this is a bug, as it seems unintuitive to me.</p></li>
</ul>

<hr>

<p>Note both compilers work properly if instead of <em>lambda expressions</em> I use some old-fashioned <code>struct</code> instances:</p>

<pre><code>struct s0
{
    auto operator()(a x) const { x.foo(); }
};

struct s1
{
    template &lt;typename T&gt;
    auto operator()(T x) const { x.bar(); }
};

auto os = overload(s0{}, s1{});
os(a{}); // OK!
</code></pre>

<p>I would expect the lambdas to be roughly equivalent to <code>s0</code> and <code>s1</code>, so this is even more surprising.</p>

<hr>

<p>This is the way I'm producing the overload set:</p>

<pre><code>template &lt;typename... Fs&gt;
struct overloader : Fs...
{
    template &lt;typename... FFwds&gt;
    overloader(FFwds&amp;&amp;... fs) : Fs{std::forward&lt;FFwds&gt;(fs)}...
    {
    }

    using Fs::operator()...;
};

template &lt;typename... Fs&gt;
auto overload(Fs&amp;&amp;... fs)
{
    return overloader&lt;std::decay_t&lt;Fs&gt;...&gt;{std::forward&lt;Fs&gt;(fs)...};
}
</code></pre>

<p>And here's a <a href="https://godbolt.org/g/maHfcb" rel="noreferrer"><strong>live example on <code>gcc.godbolt.org</code></strong></a>, showing the different behavior between the compilers.</p>

<hr>

<p><strong>Is this a g++ bug?</strong> Or is there something in the standard that makes lambdas behave differently from <code>struct</code> instances in this situation?</p>
