c – 在转换运算符不明确时选择它们

我有两种类型:

struct A { };
struct B { };

我有A或B的功能

void fnA(A); // there are a lot of these functions
void fnB(B);

我有一个类型,可以转换为A和B:

struct Foo {
    operator A();
    operator B();
};

所以我可以调用fnA和fnB:

fnA(Foo()); // fine
fnB(Foo());

现在,我有重载功能

void fn(A);
void fn(B);

我无法用Foo调用它们,因为它含糊不清:

fn(Foo()); // ambiguous,which fn is called

在这种情况下,我想fn(A)被调用.

我可以添加第三个fn重载:

inline void fn(Foo foo) {
    fn(A(foo));
}

但我不喜欢这种方式,因为我有很多fn函数,而且我不想大大增加函数数量(我有fn-like函数遍布各处,这种改变会增加接口大小,这对我不好,因为我的界面已经很大了).

一个解决方案(如果没有给出更好的替代方案,我会选择)是为Foo使用继承:

struct Foo: A {
    operator B();
};

在这种情况下,编译器将选择为fn(Foo())调用fn(A),它不再是模糊的.但是我对这个解决方案并不满意,因为Foo不是真正的A,它是对继承的误用(另一方面,它是一个比前一个更好的解决方案,因为它解决了本地问题,我不知道必须添加许多不需要的fn函数).

有没有其他方法可以解决这个问题?

注意:我想要一个不涉及显式转换的解决方案,我希望能够编写fnA(Foo()),fnB(Foo())和fn(Foo()).

解决方法

我认为你可以通过使每个fn(B)重载一个模板来实现所需的行为:

void fn(A);

template<class = void>
void fn(B);

void bar()
{
    fn(Foo());
    fn(A());
    fn(B());
}

这会导致重载决策在考虑模板化函数之前选择fn(A).必要的工作相当于放置模板< class = void>在每个函数的每个B重载之前(如果声明与定义分开,则将所有这些函数转换为模板特化).

Demo.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...