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

C++ operator== and user-defined type casts

本文关键字:类型转换 定义 运算符 C++ 用户      更新时间:2023-10-16

>我有一个名为uniVal的类,它定义了int_64双精度和字符串的转换。当我尝试将此类的对象与 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’)

但是,如果我指定 cast 为双精度以显式表示,它会编译。是否可以让 gcc 选择最接近其他参数类型的转换类型?

上级: 为每个类型组合编写自己的运算符==当然可以解决这个问题,但我希望这个类适用于所有 C++ 类型,所以我只想编写一堆转换函数,让 complier 完成其余的工作。

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

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

长版本:

编译器找到所有可行的函数(即,理论上可以通过转换或直接使用给定参数调用的所有函数),并将它们相互排名。当且仅当只有一个可行函数严格优于所有其他函数时,重载解析才会成功。此处提供了有关如何相互比较函数的精确列表("最佳可行函数"部分)。对于此特定情况,仅与以下情况相关:

如果 F1 的所有参数的隐式转换不比 F2 的所有参数的隐式转换差,并且 [...] 至少有一个 F1 参数的隐式转换优于 F2 的相应隐式转换 [...]

其余规则不适用于您的上下文,因为每个运算符的返回类型相同,并且它们不是模板(或其专用化)。 此外,您的第二个操作数不需要转换(在您的问题中存在的重载子集中),因此这一切都与uniVal转换为longdouble以及以下数字提升/转换有关。

每个转换序列的排名根据以下内容进行排序(请参阅此处;"隐式转换序列的排名"部分):

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

  2. 促销:积分提升、浮点提升

  3. 转换:整型转换、浮点转换、
  4. 浮点-整型转换、指针转换、指针到成员的转换、布尔转换、派生类到其基类的用户定义转换

在您的情况下,除了用户定义的转化之外,long intdouble都不需要额外的转化。因此,他们的排名相等(但比其他需要额外转换的候选人更好)。因此,您的呼叫是模棱两可的。

您会注意到,没有比较不同参数类型的点。这样做(不是?)是有充分理由的:毕竟,参数在函数体中可能根本不会相互结合使用(实际上,它们将处于operator==,但对于编译器来说,这只是一个像所有其他函数一样的函数),在这种情况下,比较它们的类型不会提供任何有用的信息。