简体   繁体   中英

C++ ambiguous overload for ‘operator ’

I'v read several posts here about this kind of errors, but I wasn't able to solve this one... Has soon I define the operator int and the function f, fails to compile. I tested several things by I wasn't able to solve the issue.... Thanks

ex1.cpp: In function ‘int main(int, char**)’:
ex1.cpp:35:13: error: ambiguous overload for ‘operator+’ in ‘a + 4’
ex1.cpp:35:13: note: candidates are:
ex1.cpp:35:13: note: operator+(int, int) <built-in>
In file included from ex1.cpp:3:0:
Fraccao.h:41:9: note: Fraccao operator+(const Fraccao&, const Fraccao&)
ex1.cpp:38:13: error: ambiguous overload for ‘operator+’ in ‘4 + a’
ex1.cpp:38:13: note: candidates are:
ex1.cpp:38:13: note: operator+(int, int) <built-in>
In file included from ex1.cpp:3:0:
Fraccao.h:41:9: note: Fraccao operator+(const Fraccao&, const Fraccao&)

The class:

class Fraccao {
    int numerador;
    int denominador;

public:
    Fraccao(int num = 0, int deno = 1) : numerador(num), denominador(deno) {}

    Fraccao & operator+=(const Fraccao &fra);

    Fraccao & operator*=(const Fraccao &fra);

    operator int() const;

    const Fraccao & operator++();
    const Fraccao operator++(int);

    string getAsString() const;
};

Fraccao operator +(const Fraccao &a, const Fraccao &b);
ostream & operator<<(ostream & saida, const Fraccao & fra);

And on my main:

void func(int n) {
    cout << n; // 
}

int main(int argc, char** argv) {
    //...
    d = a + b;
    const Fraccao h(7, 3);
    func(h);

    return 0;
}

You don't seem to have posted the code that actually causes the error. I guess it looks something like

Fraccao a;
Fraccao b = a + 4;
Fraccao c = 4 + a;

The problem is that your class allows implicit conversions both to and from int ; so a + 4 could be either

int(a) + 4

or

a + Fraccao(4)

with no reason to choose one over the other. To resolve the ambiguity, you could either:

  • make the conversion explicit, as above; or
  • declare either the constructor or the conversion operator (or even both) explicit so that only one (or even neither) conversion can be done implicitly.

The compiler sees two ways to interpret a + 4 . It can convert the 4 to an object of type Fraccao and use operator+(const Fraccao&, const Fraccao&) or it can convert a to type int with the member conversion operator, and add 4 to the result. The rules for overloading make this ambiguous, and that's what the compiler is complaining about. In general, as @gx_ said in a comment, this problem comes up because there are conversions in both directions. If you mark the operator int() with explicit (C++11) the code will be okay.

You have several options to fix your problem:

  • Forbid implicit conversion from int to Fraccao : Make the constructor explicit .
  • Forbid implicit conversion from Fraccao to int : Make the conversion operator explicit .

  • Convert manually on the callers side, given Fraccao f; int i; Fraccao f; int i; either int(f)+i or f+Fraccao(i) .

  • Provide additional overloads to resolve the ambiguity:

Fraccao operator +(const Fraccao &a, const Fraccao &b);
Fraccao operator +(const int a, const Fraccao &b);
Fraccao operator +(const Fraccao &a, const int b);

The latter probably means you also want:

Fraccao & operator+=(const Fraccao &fra);
Fraccao & operator+=(const int i);

And finally, if you want the latter, you can use libraries like Boost.Operators or my df.operators to support you and avoid writing the same forwarders over and over again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM