ostream& operator <<(ostream& osObject, const storageRentals& rentals)
{
osObject << rentals.summaryReport();
return osObject;
}
summaryReport()
is a void function, and it is giving me an error:
no operator "<<" matches these operands
but the error is not there if I change the summaryReport
function to an int
, but the problem I have with that is you have to return a value, and it is printing it out on the screen.
void storageRentals::summaryReport() const
{
for (int count = 0; count < 8; count++)
cout << "Unit: " << count + 1 << " " << stoUnits[count] << endl;
}
Is there any way to overload cout <<
with a void function?
You should define summartReport
taking ostream&
as parameter, as shown here:
std::ostream& storageRentals::summaryReport(std::ostream & out) const
{
//use out instead of cout
for (int count = 0; count < 8; count++)
out << "Unit: " << count + 1 << " " << stoUnits[count] << endl;
return out; //return so that op<< can be just one line!
}
then call it as:
ostream& operator <<(ostream& osObject, const storageRentals& rentals)
{
return rentals.summaryReport(osObject); //just one line!
}
By the way, it is not called "overloading cout". You should say, "overloading operator<<
for std::ostream
.
If you overload cout
, you may make some other place using code
hard to understand, or more confusing. In fact, you could make your own class to complete the work. e.g. make a class class MyPring
, and overload its operator <<
.
Your storage report implicitely is always streamed to cout.
Imagine someone calling your function this way and having the rentals on cout instead of the file.
fstream fs("out.txt");
storageRentals rentals;
fs << rentals;
Why don't you stream your class like this:
ostream& operator <<(ostream& osObject, const storageRentals& rentals)
{
for (int count = 0; count < 8; count++) {
osObject << "Unit: " << count + 1 << " " << rentals.stoUnits[count] << endl;
}
return osObject;
}
If the stoUnits member is private you need to make the stream function a friend of your storage class.
friend ostream& operator<<(ostream& osObject, const storageRentals& rentals);
There are two things you need to do here. Make storageRentals::summaryReport()
take an std::ostream&
(you can default this to std::cout
):
void storageRentals::summaryReport(std::ostream& os) const
{
for (int count = 0; count < 8; count++)
{
os << "Unit: " << count + 1 << " " << stoUnits[count] << endl;
}
}
Then call it thus:
ostream& operator <<(ostream& osObject, const storageRentals& rentals)
{
rentals.summaryReport(osObject);
return osObject;
}
Note: An advantage of making storageRentals::summaryReport()
take an std::ostream&
is that you can pass it an std::ostringstream
in your unit-tests and assert that it is providing correct output.