如何解决不明确的运算符过载问题?

How do I solve an ambiguous operator overload issue?

本文关键字:运算符 问题 不明确 何解决 解决      更新时间:2023-10-16

我有一个类Fraction定义为:

class Fraction
{
int d_numerator;
int d_denominator;
Fraction(numerator, denominator)
:
d_numerator(numerator), d_denominator(denominator)
{}
Fraction(double number)
:
d_numerator(static_cast<int>(number * 100000)), d_denominator(100000)
{}
};

我需要重载operator+以允许我添加 2 个Fraction对象:

Fraction Fraction::operator+(const Fraction& other)
{
Fraction result = Add(other); //Add() implementation omitted for brevity
return result;
}

我有一个重载的operator(double)函数,它允许我Fraction对象转换为类型double例如double b = (double)a;a属于Fraction类型。

Fraction::operator(double){//omitted for brevity}

我希望能够像这样为Fraction添加doubleFraction c = a + 2.6;

问题是这不会编译,因为有几种方法可以解释语句的转换Fraction c = a + 2.6;

我收到以下编译器错误:

错误 C2666:"分数::运算符 +":3 个重载具有类似的转换 可能是

'分数分数:
  1. :运算符 +(常量分数 &(
  2. 或内置C++运算符+(双精度、双精度(
  3. 或内置C++运算符+(浮点型、双精度型(

我认为这样做的本质是,编译器应该:

  1. 使用operator(double)重载将Fraction a转换为双精度值,并将两个双精度值相加
  2. 或者,使用允许这样做的构造函数将双精度 2.6 转换为Fraction并添加两个Fractions

有没有办法强制编译器使用另一条路由的一条,或者只是让它选择其中一条。只要结果符合预期,我不介意。

谢谢

我希望

能够像这样向分数添加双精度:Fraction c = a + 2.6;

问题是这不会编译,因为有几种方法可以解释语句的转换Fraction c = a + 2.6;

您有一个隐式转换运算符(从Fractiondouble(和一个隐式转换构造函数(从doubleFraction(,两者都会导致operator+的有效匹配,并且编译器拒绝继续这种多义性。

建议explicit进行转换,但如果您真的Fraction c = a + 2.6工作,则可以选择转换为double明确。这意味着您必须static_cast<double>(a)是否要将a转换为double

我做了一个工作示例,用于在代码中添加两个带有注释的Fraction。与其他运算符一起扩展它只是一种练习。

#include <iostream>
class Fraction {
public:
Fraction(int numerator, int denominator) :
d_numerator(numerator), d_denominator(denominator) 
{}
// a converting constructor for double
Fraction(double number) :
d_numerator(static_cast<int>(number * 1000000)), d_denominator(1000000)
{}
// add a Fraction to *this
Fraction& operator+=(const Fraction& o) {
d_numerator = d_numerator * o.d_denominator + o.d_numerator * d_denominator;
d_denominator *= o.d_denominator;
return *this;
}
// explicit conversion to double
explicit operator double() const {
return static_cast<double>(d_numerator) / d_denominator;
}
private:
int d_numerator;
int d_denominator;
};
// A free function to add two Fractions - take the left hand side by value
// and you can return the same object (after having added the right hand side to it).
Fraction operator+(Fraction a, const Fraction& b) {
// use the member operator+=
return a += b;
}

完整演示

在演示中,我使用了 C++17 函数std::gcd因为在处理分数时让数字尽可能小是很好的,并且它具有流式传输以支持打印。