C ++运算符==和用户定义的类型转换

时间:2017-04-10 20:40:15

标签: c++ gcc

我有一个名为uniVal的类,定义了转换为int_64 double和string。当我尝试将此类的对象与int进行比较时,GCC说: 候选人是:

operator==(int, int) <built-in>
operator==(int64_t {aka long int}, int) <built-in>
operator==(unsigned int, int) <built-in>
operator==(long unsigned int, int) <built-in>
operator==(float, int) <built-in>
operator==(double, int) <built-in>
error: ambiguous overload for ‘operator==’ (operand types are ‘uniVal’ and ‘int’)

但是如果我指定强制转换为double,那么它将被编译。是否可以使gcc选择最接近其他参数类型的转换类型?

UPD: 为每个类型组合编写自己的运算符==将会,offcourse,解决这个问题,但我希望这个类能够运行所有c ++类型,所以我只想编写一堆转换函数并让编译器完成其余的工作。

1 个答案:

答案 0 :(得分:0)

  

是否可以让gcc选择最接近其他参数类型的转换类型?

简短版本:不,因为在重载决策中,不考虑每个参数类型的关系。

长版:

编译器找到所有可行的函数(即,理论上可以通过转换或直接使用给定参数调用的所有函数)并将它们相互排序。当且仅当一个可行功能严格优于所有其他功能时,过载分辨率才会成功。有关如何相互比较函数的精确列表here(“最佳可行功能”部分)。对于这种特殊情况,只有以下内容是相关的:

  

如果F1的所有参数的隐式转换都不比F2的所有参数的隐式转换差,并且[...]至少有一个F1的参数隐含,则确定F1比F2更好。转换优于F2 [...]

参数的相应隐式转换

其余规则不适用于您的上下文,因为每个运算符的返回类型相同,并且它们不是模板(或其特化)。 此外,您的第二个操作数不需要任何转换(在您的问题中存在的重载子集中),因此所有关于uniVallongdouble的转换以及以下数字促销/转换。

根据以下内容对每个转换序列进行排名(请参阅here;“隐式转换序列排名”部分):

  1. 完全匹配:无需转换,左值到右值转换,限定转换,用户定义的类类型转换为同一类

  2. 推广:整体推广,浮动促销

  3. 转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔转换,用户定义的派生类转换为它的基础

  4. 在您的情况下,除了您的用户定义转化之外,long intdouble都不需要额外的转化。因此,它们彼此之间的排名相同(但是比 需要额外转换的其他候选者更好)。因此,您的电话不明确。

    您会注意到没有必要比较不同参数的类型。这是(不是?)完成的原因:毕竟,参数可能在函数体中根本不能彼此结合使用(实际上,它们将在operator==中,但对于编译器而言只是像所有其他人一样的函数)在这种情况下,比较它们的类型不会提供任何有用的信息。