我有两种类型:
struct A { };
struct B { };
Run Code Online (Sandbox Code Playgroud)
我有功能A或B:
void fnA(A); // there are a lot of these functions
void fnB(B);
Run Code Online (Sandbox Code Playgroud)
我有一个类型,可转换为A和B:
struct Foo {
operator A();
operator B();
};
Run Code Online (Sandbox Code Playgroud)
所以,我可以打电话fnA和fnB:
fnA(Foo()); // fine
fnB(Foo());
Run Code Online (Sandbox Code Playgroud)
现在,我有重载功能:
void fn(A);
void fn(B);
Run Code Online (Sandbox Code Playgroud)
我不能打电话给他们Foo,因为它含糊不清:
fn(Foo()); // ambiguous, which fn is called
Run Code Online (Sandbox Code Playgroud)
我希望fn(A)在这种情况下被召唤.
我可以添加第三个fn重载:
inline void fn(Foo foo) {
fn(A(foo));
}
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这种方式,因为我有很多fn功能,而且我不想大大增加功能的数量(我有fn类似的功能散布在各处,这种改变会增加接口大小,对我来说不好,因为我的界面已经很大了).
另一个解决方案(如果没有给出更好的替代方案,我会选择)是使用继承Foo:
struct Foo: A {
operator B();
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器会选择打电话fn(A)的fn(Foo()),这一点也不含糊了.但是我不满意这个解决方案,因为Foo它不是真的A,它是对继承的误用(另一方面,它是一个比前一个更好的解决方案,因为它解决了本地问题,我没有添加很多不需要的fn功能).
有没有其他方法可以解决这个问题?
注:我想有一个解决方案,不涉及显式转换,我想能写fnA(Foo()),fnB(Foo())和fn(Foo()).
一个花哨的模板包装器怎么样:
void fn_impl(A);
void fn_impl(B);
template<typename x_AB = A, typename x_Foo = Foo>
void fn(x_Foo && foo)
{
return fn_impl(static_cast<x_AB>(foo));
}
fn(Foo()); // calls fn_impl(A);
fn<B>(Foo()); // calls fn_impl(B);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
77 次 |
| 最近记录: |