【发布时间】:2021-04-07 04:10:14
【问题描述】:
我正在尝试找到一种方法来指定不同类型之间隐式转换的层次结构。
假设我有两种类型,每种类型都有一个函数重载:
struct A{};
struct B{};
void f(A const& a){}
void f(B const& b){}
现在我有另一个类,它可以隐式转换为A 和B
class C{
A to_A() const{return A{} ;}
B to_B() const{return B{};}
operator A() const{return to_A() ;}
operator B() const{return to_B();}
};
事实上,由于模棱两可,我不能直接使用f。
int main(){
C c;
f(c); // ambiguous, convert c to a, o c to b??
}
我们还可以说,在有选项的情况下,转换为 B 更明智。
有没有办法在struct C 中指定两者之一(A 或B)作为首选转换?,以便main 编译并等效于@987654334 @
完整代码在这里:https://godbolt.org/z/xvz71qEhK
我丢弃的可能的附近解决方案:
- 一种明显的方法是进行一次转换(到
A)explicit,但我希望这两种转换都是隐式的。因为还有其他函数(没有像f那样重载),其中两种转换都可以是隐式的。 - 在调用位置进行显式转换,
main(){f(c.to_B());}问题是我在通用模板函数中使用它,其中模板参数可以是A、B或C。 - 对于每个模棱两可的重载都创建一个新的重载
f(C const& c){return f(c.to_B());},问题是我必须为每个可以采用A或B的重载函数执行此操作,而且我有很多。我可以拥有数十个类似f的函数,其中一些具有多个参数(组合的数量激增)。
到目前为止我所做的尝试:虽然定义层次结构将有助于选择 首选 转换,并且叶类的运算符会有偏好,但它并没有消除歧义.
https://godbolt.org/z/fYj7PP5GE
template<class CRTP>
struct base_to_A{
operator A() const{
return static_cast<CRTP const&>(*this).to_A() ;
}
};
class C : public base_to_A<C>{
A to_A() const{return A{};}
B to_B() const{return B{};}
public:
operator B() const{return to_B();}
};
玩public/protected/private 没有帮助。
【问题讨论】:
-
对我来说,这似乎更像是一个设计问题,而不是一个实现/代码问题。还要记住,隐式转换往往会使代码更难阅读、理解和维护。
-
@Someprogrammerdude,是的,我从
A和B开始,然后添加了一个可以同时在语义上同时播放的新类型。如果C与A的关系是B相等,则歧义是可以的,不知何故,我想让C与B的相关性比A更相关(出于效率目的。
标签: c++ hierarchy implicit-conversion overload-resolution