问题
Consider an example:
#include <iostream>
#include <vector>
template <class, class T>
using alias = T;
template <template <class...> class>
struct tt_wrapper{};
template <class...>
struct t_wrapper{};
struct A {
template <template <class...> class TT, class T>
void foo(alias<tt_wrapper<TT>, T>) { std::cout << "A::foo invoked" << std::endl; }
};
struct B: A {
using A::foo;
template <class U, class T>
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
};
int main() {
B b;
b.foo<std::vector>(int{});
}
According to [namespace.udecl]/15:
When a using-declaration brings names from a base class into a derived class scope, 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).
So apparently the template parameters should not be involved in member function hiding. However in our example the template parameters are brought to the signature using alias. Nevertheless clang doesn't seem to share the feeling that alias is part of the function parameter-type-list and claiming:
prog.cc:26:7: error: no matching member function for call to 'foo'
b.foo<std::vector>(int{});
~~^~~~~~~~~~~~~~~~
prog.cc:21:10: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'U'
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
^
1 error generated.
I've intensionally omitted gcc in consideration as it involve template parameter list in the hiding process. Is clang right?
回答1:
A::foo
and B::foo
has
- same name (
foo
) - parameter-type-list (
T
!!!) - cv-qualification (not
const
, not volatile) - ref-qualifier (None)
template parameter list is not taken into account.
The method in base class is not virtual, so hiding and not overriding.
Demo of the fact that the parameter-type-list is T
.
来源:https://stackoverflow.com/questions/46805276/are-type-aliases-used-as-type-of-function-parameter-part-of-the-function-signatu