使用特定重载函数的声明

时间:2016-01-20 09:44:28

标签: c++ c++14

此代码

struct Foo{
    void f(){
        f(0);
    }
private:
    void f(int){}
};

struct Bar : private Foo{
    using Foo::f;
};

int main() {
    Bar b;
    b.f();
}

fails to compile因为Foo::f(int)private。我对Foo::f(int)不感兴趣,我只想Foo::f() public,所以我觉得应该有办法。

我可以想到一些解决方法:

  1. Foo::f(int)重命名为Foo::p_f(int),但这是多余的,并且不允许f的重载解析
  2. 实施Bar::foo(){Foo::f();}会对多个public f
  3. 进行大量复制/粘贴
  4. 继承public来自Foo邀请UB,因为~Foo()不是virtual(并且不应该是)
  5. 制作所有f s public会让您轻松意外中断FooBar
  6. 有没有办法说using public Foo::f;?或者使用其中一个没有相关缺点的解决方法?

2 个答案:

答案 0 :(得分:0)

如果您的f(int)应该是private,并且永远不会成为公共API的一部分,那么您不应该关心将其重命名为fimpl

struct Foo{
    void f(){
        fimpl(0);
    }
private:
    void fimpl(int){}
};

另一方面,如果f(int)是公共API的通用版本,并且您还需要一个具有特定值的便捷包装器,则可以使用提供默认参数并生成{{1} } f(int)成员。

public

最后,如果你想要几个提供某些整数值的命名函数,那么我建议重命名那些包装器

struct Foo{
    void f(int = 0){}
};

答案 1 :(得分:-1)

您的代码目前从Bar Foo private推导出Foo::f()。因此,Barstruct Bar: public Foo中的私有方法。您可以通过将类声明更改为range来更改它。

对于某些背景,请参阅"私人继承"在Derived Classes下。具体而言,该部分解释了:

  

[类]使用私有成员访问说明符从基类派生,基类的所有公共成员和受保护成员都可以作为派生类的私有成员访问(除非有特权,否则永远不能访问基类的私有成员) 。