Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Use of operator + is ambiguous", although type cast is declared as explicit

Tags:

c++

oop

I' ve been trying to make a small library for working with big integers, just as practice, but I get this error for no apparent reason:

Use of overloaded operator '+' is ambiguous (with operand types 'BigNum::BigInt' and 'int')

This is the class definition:

namespace BigNum {

    class BigInt {
    public:
        BigInt();
        BigInt(int64_t n);
        BigInt(std::string s);

        friend std::istream& operator>> (std::istream& in, BigInt& n);
        friend std::ostream& operator<< (std::ostream& out, BigInt n);

        friend bool operator< (const BigInt& a, const BigInt& b);
        friend bool operator> (const BigInt& a, const BigInt& b);
        friend bool operator== (const BigInt& a, const BigInt& b);
        friend bool operator!= (const BigInt& a, const BigInt& b);
        friend bool operator<= (const BigInt& a, const BigInt& b);
        friend bool operator>= (const BigInt& a, const BigInt& b);

        operator bool();
        explicit operator int();
        friend void swap (BigInt& a, BigInt& b);

        friend BigInt operator+ (BigInt a, BigInt b);

    private:
        std::vector<int> digits; 
        std::size_t number_of_digits;
    };
}

And these are the methods used:

BigNum::BigInt::BigInt(int64_t n) {

    if (n == 0) {
        BigInt();
        return;
    }

    // The number is stored in reverse
    for (; n; n /= 10)
        digits.emplace_back(n % 10);

    number_of_digits = digits.size();
}

std::ostream& BigNum::operator<< (std::ostream& out, BigNum::BigInt n) {

    for (auto it = n.digits.rbegin(); it != n.digits.rend(); ++it)
        out << *it;

    return out;
}

void BigNum::swap (BigNum::BigInt& a, BigNum::BigInt& b) {

    BigNum::BigInt temp(a);
    a = b;
    b = temp;
}

BigNum::BigInt BigNum::operator+ (BigNum::BigInt a, BigNum::BigInt b) {

    if (a < b)
        BigNum::swap(a, b);

    BigNum::BigInt result(a);

    int transport = 0;
    for (std::size_t i = 0; i < b.number_of_digits; ++i) {

        result.digits[i] += b.digits[i] + transport;
        transport         = result.digits[i] / 10;
        result.digits[i] %= 10;
    }

    if (transport)
        result.digits.emplace_back(transport);

    ++result.number_of_digits;

    return result;
}

If I write something like:

BigNum::BigInt a = 2;
BigNum::BigInt b = a + 1;

I get that error. I've made the int typecast explicit, but it didn't help out. I don't want to also make the constructor explicit, as that will mean that I'll no longer be able to assign an int to a BigInt (like I did in the previous example). How can I fix this?

like image 299
Semetg Avatar asked Dec 14 '25 02:12

Semetg


1 Answers

It's not enough to have one explicit conversion operator, you need to make sure that every conversion to a built-in type is explicit. In particular, you should try

explicit operator bool();

to prevent a + 1 from matching the conversion-then-promotion sequence (int)(bool)a and calling operator+(int, int).

like image 114
Ben Voigt Avatar answered Dec 16 '25 17:12

Ben Voigt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!