below is a MWE that compiles fine with g++ but fails with clang
(tested version 6.0.1 on a GNU/Linux box):
clang-problem.cpp:19:7: error:
no matching member function for call to 'zip'
bex.zip <&B::fun> ();
~~~~^~~~~~~~~~~~~
clang-problem.cpp:13:8: note: candidate template ignored:
invalid explicitly-specified argument for template parameter 'mf'
void zip () { }
^
To my best knowledge, the code is valid C++. This means there are two
possible corrolaries: either I'm wrong, and it is not valid C++
according to the standard, or clang++ has a bug. Hopefully, it's the
former.
Yeah, looks like a bug in Clang to me - CC’ing Richard Smith in case this is quick/easy/obvious to him. Here’s my slightly modified test case comparing Clang and GCC’s behavior, and adding a non-member overload situation to demonstrate that that works on both compilers: https://godbolt.org/z/cTq06R
The rule for determining when a base class function declaration introduced by a using-declaartion is hidden by a derived class function declaration does not take the template parameter list into account: http://eel.is/c++draft/namespace.udecl#15.sentence-1
So clang’s behaviour is conforming and gcc’s behaviour is not. At the very least, though, we should issue a warning for the using declaration, because this is a surprising rule.
The rule for determining when a base class function declaration
introduced by a using-declaration is hidden by a derived class
function declaration does not take the template parameter list into
account: [namespace.udecl]
Our main lilypond developer disagrees. He writes:
This link states:
When a using-declarator brings declarations from a base class into
a derived class, member functions and member function templates in
the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list,
cv-qualification, and ref-qualifier (if any) in a base class
(rather than conflicting).
The parameter-type-list is a different one in this example since
they contain a different member function pointer type. Which is the
reason we need the whole hooplahoop in the first place.
The rule for determining when a base class function declaration
introduced by a using-declaration is hidden by a derived class
function declaration does not take the template parameter list into
account: [namespace.udecl]
Our main lilypond developer disagrees. He writes:
This link states:
When a using-declarator brings declarations from a base class into
a derived class, member functions and member function templates in
the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list,
cv-qualification, and ref-qualifier (if any) in a base class
(rather than conflicting).
The parameter-type-list is a different one in this example since
they contain a different member function pointer type. Which is the
reason we need the whole hooplahoop in the first place.
Isn’t it template-parameter-list that is different rather than parameter-type-list?
The rule for determining when a base class function declaration
introduced by a using-declaration is hidden by a derived class
function declaration does not take the template parameter list into
account: http://eel.is/c++draft/namespace.udecl#15.sentence-1
Our main lilypond developer disagrees. He writes:
This link states:
When a using-declarator brings declarations from a base class into
a derived class, member functions and member function templates in
the derived class override and/or hide member functions and member
function templates with the same name, parameter-type-list,
cv-qualification, and ref-qualifier (if any) in a base class
(rather than conflicting).
The parameter-type-list is a different one in this example since
they contain a different member function pointer type. Which is the
reason we need the whole hooplahoop in the first place.
Isn’t it template-parameter-list that is different rather than parameter-type-list?