C++ 如何同时拥有转换构造函数和转换运算符?

C++ 如何同时拥有转换构造函数和转换运算符?,c++,type-conversion,operator-overloading,C++,Type Conversion,Operator Overloading,考虑一下这个简单的C++-17程序: #include <iostream> #include <math.h> using namespace std; class Fraction { public: int nom; int den; Fraction operator+ (const Fraction& other) { int nn = nom * other.den +

考虑一下这个简单的C++-17程序:

#include <iostream>
#include <math.h>
using namespace std;


class Fraction {
public:
    int     nom;
    int     den;
    Fraction operator+ (const Fraction& other) {
        int nn = nom * other.den +
            den * other.nom;
        int dd = den * other.den;
        return Fraction(nn, dd);
    }
    Fraction(int nn, int dn): nom(nn), den(dn) { }
    Fraction(int nn): nom(nn), den(1) { }
    operator double() const { return double(nom) / den; }
};

ostream& operator<<(ostream& os, const Fraction& frac) {
    return os << frac.nom << '/' << frac.den;
}


int main() {
    Fraction f1(1, 4);
    cout << "f1 = " << f1 << endl << "f1+2 = " << (f1 + 2) << endl;
    return 0;
}
#包括
#包括
使用名称空间std;
类分数{
公众:
国际名称;
int den;
分数运算符+(常数分数和其他){
int nn=nom*other.den+
den*other.nom;
int dd=den*other.den;
收益率(nn,dd);
}
分数(intnn,intdn):nom(nn),den(dn){
分数(int-nn):nom(nn),den(1){
运算符double()常量{return double(nom)/den;}
};

ostream&operator使一个或两个转换函数
显式
。这将防止您的友好编译器在基于隐式转换序列选择运算符
+
重载时隐式使用它们

explicit Fraction(int nn): nom(nn), den(1) { }
explicit operator double() const { return double(nom) / den; }

请记住,它会阻止所有使用这些函数进行隐式转换。

使一个或两个转换函数
显式
。这将防止您的友好编译器在基于隐式转换序列选择运算符
+
重载时隐式使用它们

explicit Fraction(int nn): nom(nn), den(1) { }
explicit operator double() const { return double(nom) / den; }

请记住,它会阻止所有使用这些函数进行隐式转换。

对于这个错误,编译器正在抱怨,因为它无法自行解决歧义。正如它正确指出的那样,有两种可能的解决方案,如果没有您的额外见解,它不知道选择哪一种

您希望如何计算
(f1+2)
,如果您想要分数添加,建议将调用者更改为
(f1+Fraction(2))

如果您想要双重加法,请将其更改为
(双重(f1)+2)


总之,您可以继续进行从分数到双精度的转换和从整数到分数的构造,但是当编译器存在歧义时,您需要显式指定所需的行为

由于错误,编译器正在抱怨,因为它无法自行解决歧义。正如它正确指出的那样,有两种可能的解决方案,如果没有您的额外见解,它不知道选择哪一种

您希望如何计算
(f1+2)
,如果您想要分数添加,建议将调用者更改为
(f1+Fraction(2))

如果您想要双重加法,请将其更改为
(双重(f1)+2)

总之,您可以继续进行从分数到双精度的转换和从整数到分数的构造,但是当编译器存在歧义时,您需要显式指定所需的行为