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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With