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

时间:2016-09-22 07:16:10

标签: c++ inheritance using

考虑使用b的两个重载方法的类foo

struct b {
    void foo(float) {}
    void foo(const char *) {}
};

如果我从d派生private b,我可以use using to expose b's foo

struct d : private b {
    using b::foo;
};

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

d t;
t.foo(3.13); // d should have this overload
t.foo("hello"); // d shouldn't have this overload

我尝试了各种写作方式

    using b::<i mean only void foo(float), dammit!>

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

另外,显然可以在d中定义所需的重载调用b的重载

struct d : private b {
    void foo(float f) { b::foo(f); }
};

但问题是,是否可以仅使用using简洁地执行此操作。

2 个答案:

答案 0 :(得分:8)

不,那是不可能的。与任何其他声明一样,using声明对名称进行操作。

using b::foo;名称 foo引入包含范围的声明中,以便它引用b::foo引用的任何内容。名称b::foo指的是&#34;系列&#34;重载函数,所以在using-declaration之后,名称foo引用相同的。

如果你想发布&#34;只有一些重载,你必须使用你已经显示的蹦床功能来实现:

struct d : private b {
    void foo(float f) { b::foo(f); }
};

答案 1 :(得分:5)

正如his answer中@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);
}

这不是您想要的,但它是获得几乎相同结果的解决方法。

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

  

请注意,删除的重载与没有重载的重载不同。如果错过了可能会选择不同的重载,而如果删除则可能会被选中并生成错误。

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