如何解决不明确的运算符过载问题?
How do I solve an ambiguous operator overload issue?
我有一个类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
添加double
:Fraction c = a + 2.6;
问题是这不会编译,因为有几种方法可以解释语句的转换Fraction c = a + 2.6;
我收到以下编译器错误:
错误 C2666:"分数::运算符 +":3 个重载具有类似的转换 可能是
'分数分数:- :运算符 +(常量分数 &(
- 或内置C++运算符+(双精度、双精度(
- 或内置C++运算符+(浮点型、双精度型(
我认为这样做的本质是,编译器应该:
- 使用
operator(double)
重载将Fraction a
转换为双精度值,并将两个双精度值相加 - 或者,使用允许这样做的构造函数将双精度 2.6 转换为
Fraction
并添加两个Fractions
?
有没有办法强制编译器使用另一条路由的一条,或者只是让它选择其中一条。只要结果符合预期,我不介意。
谢谢
能够像这样向分数添加双精度:
Fraction c = a + 2.6;
问题是这不会编译,因为有几种方法可以解释语句的转换
Fraction c = a + 2.6
;
您有一个隐式转换运算符(从Fraction
到double
(和一个隐式转换构造函数(从double
到Fraction
(,两者都会导致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
因为在处理分数时让数字尽可能小是很好的,并且它具有流式传输以支持打印。
- 一个关于在C++中重载布尔运算符的问题
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- 运算符继承和 cpp 核心准则 c.128 的问题
- 在C++中使用重载提取运算符时出现问题
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 关于条件块的问题与&&运算符有关
- 重载运算符与添加问题
- 加、乘、除、减复数的问题 C++ - 运算符重载
- C++中的三元条件运算符问题
- 重载+运算符问题与其他类中的友元函数混合
- C++中带有 cout 运算符问题的向量
- C++运算符=问题
- 模板类型的重载解析和运算符<<问题 - 第 2 部分
- 两相查找运算符<<问题?
- C++ 运算符问题 ()
- C++:如何将普通话(字符串)分配给用户使用数组输入的数字 &运算符问题
- 布尔运算符问题
- 相等运算符问题 (C++)
- 简单的运算符+问题躲避了我
- 重载运算符 I/O 问题