4

考虑一个例子:

#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{});
}

根据[namespace.udecl]/15

当 using-declaration 将基类中的名称带入派生类范围时,派生类中的成员函数和成员函数模板会覆盖和/或隐藏具有相同名称、参数类型列表、cv 的成员函数和成员函数模板-qualification 和 ref-qualifier(如果有)在基类中(而不是冲突)

所以显然模板参数不应该参与成员函数隐藏。但是在我们的示例中,模板参数使用别名被带到签名中。尽管如此, clang似乎并不认同 alias 是函数参数类型列表的一部分并声称:

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.

我故意省略了 gcc,因为它涉及隐藏过程中的模板参数列表。叮当是对的吗?

4

1 回答 1

2

A::foo并且B::foo

  • 同名 ( foo)
  • 参数类型列表 ( T!!!)
  • cv-qualification (not const, not volatile)
  • 引用限定符(无)

不考虑模板参数列表。

基类中的方法不是虚拟的,所以隐藏而不是覆盖。

演示参数类型列表为T.

于 2017-10-18T08:40:10.853 回答