简体   繁体   中英

g++ compiler giving << type errors for expressions, but works in Visual Studio

Ok, I think this might just be a version issue but I'm new to this. I have a main file that uses my overridden << operator for a BigInt class I've implemented:

BigInt a = 3;
cout << a << endl;
cout << (a+a) << endl;

In Visual Studio, the compiler understands everything just fine and it runs great. But moving over to Ubuntu 14.04, make ing with my Makefile (which uses plain g++ commands) gives me a bazillion type errors that are caused by the third line (and any other line that uses cout with an expression). If I remove the third line, it compiles great. The first error is:

main.cpp:23:8: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'BigInt')
    cout << (a+a);
         ^

This is confusing because my << operator function takes reference args:

// in BigInt.h, in class' public section:

BigInt operator+(BigInt const& other) const;
friend std::ostream & operator<<(std::ostream& os, BigInt& num);


// in BigInt.cpp:

BigInt BigInt::operator+(BigInt const& other) const {
    // call appropriate helper based on signs
    if (this->neg == other.neg) {
        return sum(other);
    }
    else {
        return difference(other);
    }
}

ostream & operator<<(ostream& os, BigInt& num) {
    if (num.dataLength == -1) {
        os << "**UNDEFINED**";
    }
    else {
        if (num.neg) os << "-";
        if (num.dataLength == 0) {
            os << "INFINITY";
        }
        else {
            // print each digit
            for (int i = num.dataLength - 1; i >= 0; i--) {
                os << (short)num.data[i];
            }
        }
    }
    return os;
}

So why does the first cout work but not the second? Is there a way to run g++ such that it can work?

ostream & operator<<(ostream& os, BigInt& num)

should take a BigInt const& num . MSVC is non-compliant with regards to this . g++ does not have this extension.

Make sure you change both the declaration in the header and the definition in the BigInt.c file. (Also, it is normal to use .c for files containing C code, and .cpp for files containing C++ code.)

The reason is that (a+a) creates a temporary BigInt , which can't be bound to a non- const reference. The first cout works because a is a local variable, not a temporary, so can be passed as a normal (non- const ) reference.

Aside from the issue with temporaries, it is good practice to apply const -correctness : make things const unless you actually need to change them. This can help prevent mistakes. Note that std::ostream& os cannot be const , you really do change it by writing to it.

The issue is with

friend std::ostream & operator<<(std::ostream& os, BigInt& num);

Since you take a BigInt& num this will not work with (a+a) as that crates a temporary and you cannot take a reference to a temporary. It works in MSVS as they have an extension to allow this but g++ does not. Change it to

friend std::ostream & operator<<(std::ostream& os, const BigInt& num);

So why does the first cout work but not the second?

Your operator << takes its second argument by non-const reference. Temporaries like (a+a) cannot bind to that, so the second call is illegal. MSVC allows that as an extension, but it is not standard C++.

Is there a way to run g++ such that it can work?

No. Fix your operator to use a const reference instead.

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