Looks like a Clang bug to me.
The general rule is that member functions of the same name in different base classes do not overload. For example:
struct Foo { void bar(); };
struct Baz { void bar(int); };
struct Quux : Foo, Baz { };
int main() { Quux().bar(); } // error on both GCC and Clang
For whatever reason, Clang fails to diagnose this ambiguity for operator()
.
A using-declaration
lifts the named base class members to the derived class scope, allowing them to overload. Hence:
struct Quux_2 : Foo, Baz { using Foo::bar; using Baz::bar; };
Quux_2().bar(); // OK.
In the working version of the code, the using
declarations recursively bring every operator()
declaration in the template arguments into the scope of the most derived class, allowing them to overload.