如何使父类的模板方法在子类中可见?

How to make a parent's template method visible from a child class?

本文关键字:子类 何使 父类 模板方法      更新时间:2023-10-16

下面是一个示例代码:

#include <memory>
class A {
  public:
    template <class T> void f(std::unique_ptr<T>, int) {}
  private:
    virtual void f(int) = 0;
};
class B: public A {
  public:
    using A::f;
  private:
    virtual void f(int) override {}
};
int main() {
  std::unique_ptr<float> a;
  B* b = new B;
  b->f(std::move(a), 1);
  return 0;
}

当我使用 clang++ 编译它时,出现错误:

'f' is a private member of 'A'
using A::f;
         ^

如何使模板方法f(std::unique_ptr<T>, int)class B可见?


注意:如果将虚拟方法A::f(int)移动到公共部分 - 一切正常。

通过给它起与完全不相关的私有虚拟f不同的名称。

具有不同

重载具有不同访问控制级别的重载功能既不起作用也没有意义。只有当函数实际上执行相同(或给定参数的可比性)事情时,才应使用相同的名称,但将一个公共和一个私有化是没有意义的。

如果您在私有虚拟上有一个公共包装器(这很常见,请参阅 std::basic_streambuf),只需为其中一个添加合适的前缀/后缀(std::basic_streambuf在公共场合使用pub,但通常将privimpl_添加到私有虚拟中更有意义。

您不能为此使用using using因为无法区分模板和虚拟f。有效的是一个简单的转发器:

class B: public A {
public:
  template <class T> void f(std::unique_ptr<T> p, int i)
  {
    A::f<T>(std::move(p),i);
  }
private:
  virtual void f(int) override {}
};