C++ 如何解决不明确的运算符重载问题?
我有一个类C++ 如何解决不明确的运算符重载问题?,c++,operator-overloading,C++,Operator Overloading,我有一个类分数定义为: 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 * 10
分数定义为:
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)
{}
};
我有一个重载的操作符(double)
函数,它允许我将分数
对象强制转换为类型double
,例如double b=(double)a代码>其中a
属于Fraction
类型
Fraction::operator(double){//omitted for brevity}
我希望能够像这样将一个double
添加到分数中:分数c=a+2.6代码>
问题是这不会编译,因为有几种方法可以解释语句分数c=a+2.6的转换代码>
我发现以下编译器错误:
错误C2666:“分数::运算符+”:3个重载具有类似的转换
可能是
'分数分数::运算符+(常数分数&)
或内置C++操作符+(double,double)
或内置C++操作符+(浮点,double)< /LI>
我认为其本质是,编译器应该:
使用操作符(double)
重载将分数a
转换为双精度,并将两个双精度相加
或者,使用允许此操作的构造函数将双精度2.6转换为分数
,然后添加两个分数
有没有办法强迫编译器使用另一条路径中的一条,或者任由它选择其中一条。只要结果如预期,我不介意
谢谢
我希望能够给这样的分数加上一个双精度:分数c=a+2.6代码>
问题是这将不会编译,因为有几种解释语句转换的方法分数c=a+2.6
您有一个隐式转换运算符(从Fraction
到double
)和一个隐式转换构造函数(从double
到Fraction
),两者都会导致运算符+
的有效匹配,并且编译器拒绝继续这种歧义
建议进行显式转换
,但如果您确实希望分数c=a+2.6
起作用,您可以满足于进行双显式转换。这意味着,如果您想将a
转换为double
,则必须static\u cast(a)
我制作了一个工作示例,用于在代码中添加两个带有注释的分数。用其他操作符扩展它只是一个练习
#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;
}
#包括
类分数{
公众:
分数(整数分子、整数分母):
d_分子(分子),d_分母(分母)
{}
//double的转换构造函数
分数(双数):
d_分子(静态(数字*1000000)),d_分母(1000000)
{}
//在*上加一个分数
分数和运算符+=(常数分数和o){
d_分子=d_分子*o.d_分母+o.d_分子*d_分母;
d_分母*=o.d_分母;
归还*这个;
}
//显式转换为双精度
显式运算符double()常量{
返回静态(d_分子)/d_分母;
}
私人:
int d_分子;
int d_分母;
};
//添加两个分数的自由函数-按值取左侧
//您可以返回相同的对象(在向其添加右侧之后)。
分数运算符+(分数a、常数分数和b){
//使用成员运算符+=
返回a+=b;
}
在演示中,我使用了C++17函数,因为在处理分数时,数字越小越好,而且它还支持流式打印
我希望能够给这样的分数加上一个双精度:分数c=a+2.6代码>
问题是这将不会编译,因为有几种解释语句转换的方法分数c=a+2.6
您有一个隐式转换运算符(从Fraction
到double
)和一个隐式转换构造函数(从double
到Fraction
),两者都会导致运算符+
的有效匹配,并且编译器拒绝继续这种歧义
建议进行显式转换
,但如果您确实希望分数c=a+2.6
起作用,您可以满足于进行双显式转换。这意味着,如果您想将a
转换为double
,则必须static\u cast(a)
我制作了一个工作示例,用于在代码中添加两个带有注释的分数。用其他操作符扩展它只是一个练习
#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;
}
#包括
类分数{
公众:
分数(整数分子、整数分母):
d_分子(分子),d_分母(分母)
{}
//double的转换构造函数
分数(双数):
d_分子(静态(数字*1000000)),d_分母(1000000)
{}
//在*上加一个分数
分数和运算符+=(常数分数和o){
d_分子=d_分子*o.d_分母+o.d_分子*d_分母;
d_分母*=o.d_分母;
归还*这个;
}
//显式转换为双精度
显式运算符double()常量{
返回静态(d_分子)/d_分母;
}
私人:
int d_分子;
int d_分母;
};
//添加两个分数的自由函数-按值取左侧
//您可以返回相同的对象(在向其添加右侧之后)。
分数运算符+(分数a、常数分数和b){
//使用成员运算符+=
返回a+=b;
}
在演示中,我使用了C++17函数,因为在处理分数时,数字越小越好,并且它具有支持打印的流媒体功能。