转换构造函数不会将“2”转换为“2”进入运算符 + 中的用户定义类型

发布于 2024-12-02 09:03:45 字数 4881 浏览 0 评论 0原文

我有一个名为 Fraction 的类:

#ifndef FRACTION_H
#define FRACTION_H

#include <iostream>
using namespace std;

class Fraction
{
  // data
  int m_iNom;
  int m_iDenom;

  // operations
  int gcd (int i, int j);
  void reduce ();

public:

 Fraction (int nn=0, int dn=1); // 1 declaration = 3 constructors
 Fraction (const Fraction& fr); //C.Ctor
 ~Fraction (); //Dtor
 Fraction& operator = (const Fraction &fr); //assignment

 Fraction& operator ++ (); // prefix - ++a
  const Fraction operator ++ (int); // postfix - a++

  friend const Fraction operator + (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator - (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator * (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator / (const Fraction &f1, const Fraction &f2);

 Fraction& operator += (const Fraction &f);

  operator double () { return double (m_iNom) / m_iDenom; } //casting operator

  friend istream& operator >> (istream &is, Fraction &f);
  friend ostream& operator << (ostream &os, const Fraction &f);
  const int& operator[] (int i) const;
  int& operator [] (int i);


};
#endif

带有下一个实现文件:

#include "Fraction.h"
#include <iostream>
using namespace std;


Fraction::Fraction (int nn, int dd) :
   m_iNom (nn), m_iDenom (dd) {
  if (m_iDenom == 0)
  m_iDenom = 1;
 reduce ();
 cout<<"Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
}


Fraction::Fraction (const Fraction & fr){
 m_iNom=fr.m_iNom;
 m_iDenom=fr.m_iDenom;
 cout<<"C.Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
}

Fraction::~Fraction() {
 cout<<"del: "<<m_iNom<<"/"<<m_iDenom<<endl;
}


int Fraction::gcd (int i, int j) {
  if ((i == 0) || (j == 0))
   return i + j;
  while (i %= j) {
   int t = i;
  i = j;
  j = t;
 }
  return j;
}


void Fraction::reduce () {
  int g = gcd (m_iNom, m_iDenom);
 m_iNom /= g;
 m_iDenom /= g;
}


const Fraction operator + (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom + f1.m_iDenom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator - (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom - f1.m_iDenom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator * (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator / (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom;
  int dd = f1.m_iDenom * f2.m_iNom;
  return Fraction (nn, dd);
}


Fraction& Fraction::operator = (const Fraction &f)
{
 m_iNom = f.m_iNom;
 m_iDenom = f.m_iDenom;
 cout<<"OP = - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
  return *this;
}


Fraction& Fraction::operator += (const Fraction &f) {
 (*this) = (*this) + f;
  return *this;
}


Fraction& Fraction::operator ++ ()
{
 m_iNom += m_iDenom;
 reduce ();
  return *this;
}


const Fraction Fraction::operator ++ (int)
{
  int nn = m_iNom;
  int dd = m_iDenom;
 m_iNom += m_iDenom;
 reduce ();
  return Fraction (nn, dd);
}


istream& operator >> (istream &is, Fraction &frac)
{
  char divSign;
 is >> frac.m_iNom >> divSign >> frac.m_iDenom;
  if (frac.m_iDenom == 0)
  frac.m_iDenom = 1;
 frac.reduce ();
  return is;
}


ostream& operator << (ostream& os, const Fraction &frac)
{
  return os << frac.m_iNom << "/" << frac.m_iDenom;
}


int& Fraction::operator [] (int i){
 cout<<"reg []"<<endl;
  if (i==1)
   return m_iNom;
  return m_iDenom;
}


const int& Fraction::operator[] (int i) const{
 cout<<"const []"<<endl;
  if (i==1)
   return m_iNom;
  return m_iDenom;
}

并且我正在尝试执行操作 Fraction f4=f2+2; 但我收到以下编译器错误:

..\main.cpp:13: error: ambiguous overload for 'operator+' in 'f2 + 2'
..\main.cpp:13: note: candidates are: operator+(double, int) <built-in>
..\Fraction.h:27: note:                 const Fraction operator+(const Fraction&, const Fraction&)

但这怎么可能,如果我有一个转换构造函数(请注意 .h 文件中具有默认值的 Ctor),其一个参数假设将“2”转换为分数……那么问题可能是什么?

谢谢 Ronen

编辑:

这是主文件(如果有帮助的话)

#include <iostream>
using namespace std;

#include "Fraction.h"

int main() {
    Fraction f1(1,2);
    Fraction f2(2);
    Fraction f3;

    Fraction f4=f2+2;  // problem's here 
    f2+f2;
    Fraction f5=f2-f1+f4;
    return 0;
}

I have a class called Fraction :

#ifndef FRACTION_H
#define FRACTION_H

#include <iostream>
using namespace std;

class Fraction
{
  // data
  int m_iNom;
  int m_iDenom;

  // operations
  int gcd (int i, int j);
  void reduce ();

public:

 Fraction (int nn=0, int dn=1); // 1 declaration = 3 constructors
 Fraction (const Fraction& fr); //C.Ctor
 ~Fraction (); //Dtor
 Fraction& operator = (const Fraction &fr); //assignment

 Fraction& operator ++ (); // prefix - ++a
  const Fraction operator ++ (int); // postfix - a++

  friend const Fraction operator + (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator - (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator * (const Fraction &f1, const Fraction &f2);
  friend const Fraction operator / (const Fraction &f1, const Fraction &f2);

 Fraction& operator += (const Fraction &f);

  operator double () { return double (m_iNom) / m_iDenom; } //casting operator

  friend istream& operator >> (istream &is, Fraction &f);
  friend ostream& operator << (ostream &os, const Fraction &f);
  const int& operator[] (int i) const;
  int& operator [] (int i);


};
#endif

with the next implementation file :

#include "Fraction.h"
#include <iostream>
using namespace std;


Fraction::Fraction (int nn, int dd) :
   m_iNom (nn), m_iDenom (dd) {
  if (m_iDenom == 0)
  m_iDenom = 1;
 reduce ();
 cout<<"Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
}


Fraction::Fraction (const Fraction & fr){
 m_iNom=fr.m_iNom;
 m_iDenom=fr.m_iDenom;
 cout<<"C.Ctor - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
}

Fraction::~Fraction() {
 cout<<"del: "<<m_iNom<<"/"<<m_iDenom<<endl;
}


int Fraction::gcd (int i, int j) {
  if ((i == 0) || (j == 0))
   return i + j;
  while (i %= j) {
   int t = i;
  i = j;
  j = t;
 }
  return j;
}


void Fraction::reduce () {
  int g = gcd (m_iNom, m_iDenom);
 m_iNom /= g;
 m_iDenom /= g;
}


const Fraction operator + (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom + f1.m_iDenom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator - (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom - f1.m_iDenom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator * (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iNom;
  int dd = f1.m_iDenom * f2.m_iDenom;
  return Fraction (nn, dd);
}


const Fraction operator / (const Fraction &f1, const Fraction &f2) {
  int nn = f1.m_iNom * f2.m_iDenom;
  int dd = f1.m_iDenom * f2.m_iNom;
  return Fraction (nn, dd);
}


Fraction& Fraction::operator = (const Fraction &f)
{
 m_iNom = f.m_iNom;
 m_iDenom = f.m_iDenom;
 cout<<"OP = - Fraction: "<<m_iNom<<"/"<<m_iDenom<<endl;
  return *this;
}


Fraction& Fraction::operator += (const Fraction &f) {
 (*this) = (*this) + f;
  return *this;
}


Fraction& Fraction::operator ++ ()
{
 m_iNom += m_iDenom;
 reduce ();
  return *this;
}


const Fraction Fraction::operator ++ (int)
{
  int nn = m_iNom;
  int dd = m_iDenom;
 m_iNom += m_iDenom;
 reduce ();
  return Fraction (nn, dd);
}


istream& operator >> (istream &is, Fraction &frac)
{
  char divSign;
 is >> frac.m_iNom >> divSign >> frac.m_iDenom;
  if (frac.m_iDenom == 0)
  frac.m_iDenom = 1;
 frac.reduce ();
  return is;
}


ostream& operator << (ostream& os, const Fraction &frac)
{
  return os << frac.m_iNom << "/" << frac.m_iDenom;
}


int& Fraction::operator [] (int i){
 cout<<"reg []"<<endl;
  if (i==1)
   return m_iNom;
  return m_iDenom;
}


const int& Fraction::operator[] (int i) const{
 cout<<"const []"<<endl;
  if (i==1)
   return m_iNom;
  return m_iDenom;
}

and I'm trying to do the action Fraction f4=f2+2; but I get the following compiler error:

..\main.cpp:13: error: ambiguous overload for 'operator+' in 'f2 + 2'
..\main.cpp:13: note: candidates are: operator+(double, int) <built-in>
..\Fraction.h:27: note:                 const Fraction operator+(const Fraction&, const Fraction&)

But how could that be , if I have a conversion Constructor (please notice the Ctor in the .h file with the default values) with one argument which is suppose to convert the "2" into a Fraction ...then what's might the be the problem ?

thanks
Ronen

Edit :

here's the main file (if it would help)

#include <iostream>
using namespace std;

#include "Fraction.h"

int main() {
    Fraction f1(1,2);
    Fraction f2(2);
    Fraction f3;

    Fraction f4=f2+2;  // problem's here 
    f2+f2;
    Fraction f5=f2-f1+f4;
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掀纱窥君容 2024-12-09 09:03:45

编译器无法决定是将 f2 转换为 double 然后添加 doubleint,还是构造 Fraction从 2 然后添加两个分数。

选项:

  • 使运算符 double() 显式 (C++11)
  • 重载运算符 + 以获取整数

The compiler can't decide whether to convert f2 to double then add double and int, or to construct Fraction from 2 then add two fractions.

Options:

  • Make operator double() explicit (C++11)
  • Overload operator + to take ints
物价感观 2024-12-09 09:03:45

问题是:

operator double ()

在您的 Fraction 类中定义。

在评估时,

Fraction f4=f2+2;

编译器有 2 个选择:

第一个选择:

编译器可以使用您提供的运算符函数将 f2 转换为 double,然后可以用于调用内置运算符函数:

    operator+(double, int);

第二种选择:

编译器可以使用构造函数将 2 转换为 Fraction 对象,然后调用:

const Fraction operator+(const Fraction&, const Fraction&)

两者选择会导致歧义,然后编译器会抱怨并报告给你。

解决方案:
更改 double 运算符函数的名称。

Problem is:

operator double ()

defined inside your Fraction class.

While evaluating,

Fraction f4=f2+2;

Compiler has 2 choices:

First Choice:

The compiler can convert f2 to a double using your provided operator function and then it can be used to call the inbuilt operator function:

    operator+(double, int);

Second Choice:

The compiler can convert 2 to a object of Fraction using constructor and then call:

const Fraction operator+(const Fraction&, const Fraction&)

The two choices cause an ambiguity and then the compiler complains and reports it to you.

Solution:
Change the name of the double operator function.

无名指的心愿 2024-12-09 09:03:45

当您编写类似 f2+2 的内容时,编译器确实可以做出两种选择。

  • 它可以首先使用分数的构造函数将 2 转换为分数,然后使用分数的 + 运算符。
  • 它可以首先使用分数的双精度运算符将 f2 转换为双精度数,然后简单地将双精度数和整数相加。

您必须使构造函数显式化,或者为双精度运算符指定一个显式名称(例如 toDouble)来解决问题。

The compiler can indeed make 2 choices when you write something like f2+2.

  • It can first convert 2 to a fraction by using the fraction's constructor and then use the Fraction's + operator.
  • It can first convert f2 to a double using the Fraction's double operator, and then simply add the double and the integer

You will have to make either the constructor explicit, or give the double-operator an explicit name (e.g. toDouble) to solve the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文