`using` 仅重载一个基数 Class
`using` Only Some Overloads Of A Base Class
考虑一个 class b
有两个重载方法 foo
:
struct b {
void foo(float) {}
void foo(const char *) {}
};
如果我从 b
导出 d
private
ly,我可以 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
简洁地执行此操作。
不,那是不可能的。 using
声明,就像任何其他声明一样,作用于 names.
using b::foo;
将 name foo
引入声明的包含范围,这样它就可以引用 b::foo
所指的任何内容。名称 b::foo
指的是 "family" 个重载函数,因此在 using 声明之后,名称 foo
指的是相同的
如果您只想 "publish" 一些重载,则必须使用您展示的 trampoline 函数来实现:
struct d : private b {
void foo(float f) { b::foo(f); }
};
正如@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 的评论,值得在答案中引用:
Note that a deleted overload is not the same as not having one. If missing a different overload may be selected, while if deleted it may be instead selected and generate an error.
这是对的,上面的解决方案是否适用于 OP 主要取决于实际问题。
我不能这么说,但在某些情况下这仍然是一个可行的解决方案
考虑一个 class b
有两个重载方法 foo
:
struct b {
void foo(float) {}
void foo(const char *) {}
};
如果我从 b
导出 d
private
ly,我可以 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
简洁地执行此操作。
不,那是不可能的。 using
声明,就像任何其他声明一样,作用于 names.
using b::foo;
将 name foo
引入声明的包含范围,这样它就可以引用 b::foo
所指的任何内容。名称 b::foo
指的是 "family" 个重载函数,因此在 using 声明之后,名称 foo
指的是相同的
如果您只想 "publish" 一些重载,则必须使用您展示的 trampoline 函数来实现:
struct d : private b {
void foo(float f) { b::foo(f); }
};
正如@Angew 在
因此,您不能只选择您喜欢的,但您仍然可以反其道而行之,= 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 的评论,值得在答案中引用:
Note that a deleted overload is not the same as not having one. If missing a different overload may be selected, while if deleted it may be instead selected and generate an error.
这是对的,上面的解决方案是否适用于 OP 主要取决于实际问题。
我不能这么说,但在某些情况下这仍然是一个可行的解决方案