`using`只有一些基类的过载

Ami*_*ory 9 c++ inheritance using

考虑一个b具有两个重载方法的类foo:

struct b {
    void foo(float) {}
    void foo(const char *) {}
};
Run Code Online (Sandbox Code Playgroud)

如果我得到d private来自LY b,我可以用using揭露b的foo:

struct d : private b {
    using b::foo;
};
Run Code Online (Sandbox Code Playgroud)

但是,这会暴露所有重载.有没有办法只暴露其中一个(比方说float一个)?例如,在下面,我想最后一行编译失败:

d t;
t.foo(3.13); // d should have this overload
t.foo("hello"); // d shouldn't have this overload
Run Code Online (Sandbox Code Playgroud)

我尝试了各种写作方式

    using b::<i mean only void foo(float), dammit!>
Run Code Online (Sandbox Code Playgroud)

但无法将其中任何一个编译.

而且,显然可以d在所需的过载调用b过载中定义

struct d : private b {
    void foo(float f) { b::foo(f); }
};
Run Code Online (Sandbox Code Playgroud)

但问题是,是否有可能只是简单地做到这一点using.

Rei*_*ica 8

不,那是不可能的.一个using声明,就像任何其他声明,操作上的名字.

using b::foo;将名称 foo引入声明的包含范围,以便引用任何b::foo引用的范围.名称b::foo是指重载函数的"族",因此在使用声明之后,名称foo引用相同.

如果您只想"发布"一些重载,则必须使用您显示的trampoline函数来执行此操作:

struct d : private b {
    void foo(float f) { b::foo(f); }
};
Run Code Online (Sandbox Code Playgroud)


sky*_*ack 5

正如@Angew在他的回答中所提到的,using声明在名称空间中引入了名称.
因此,你不能只选择你喜欢的那些,但你仍然可以做相反= delete的事情和那些你不想暴露的事情:

struct B {
    void f() { }
    void f(int) { }
    void f(int, char) { }
};

struct D: B {
    using B::f;
    void f(int) = delete;
};

int main() {
    D d;
    d.f();
    d.f(0, 'c');
    // this won't work
    // d.f(0);
}
Run Code Online (Sandbox Code Playgroud)

这不是您正在寻找的,但它是获得几乎相同结果的解决方法.


它遵循@Yakk的评论,值得在答案中引用:

请注意,删除的重载与没有重载的重载不同.如果错过了可以选择不同的过载,而如果删除则可以改为选择并产生错误.

这是正确的,如果上述解决方案适用于OP主要取决于实际问题.
我不能这么说,但对某些情况来说,这仍然是一个可行的解决方案