I'm quite new to C++ and I am trying to print out a vector of Institutions, which is a type of object that I created. The creation of the object and the rest of my program runs just fine but when I try to print out the vector, the "<<" gives an error that says "operand types are std::ostream".
void PrintVector(const vector<Institution> &institutions)
{
for (int x = 0; x < institutions.size; x++)
{
cout << institutions.at(x) << endl;
}
}
I've tried to do research on what std::ostream is or what it does but since I don't know a lot about C++ (or programming in general), I can't understand any of the sites that explain it. Why won't the usual "cout <<" work in this situation? Can anybody explain to me what this means or if there is a different way to print out my vector that doesn't require this?
Any help is appreciated, thanks.
You may want to overload the ostream operator (<<) for your class Institution: https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx
ostream& operator<<(ostream& os, const Institution& inst)
{
os << inst.foo; /* some member variable */;
return os;
}
The problem is that a C++ ostream
(which cout
is) does not have any way to print out an Institution
object. You are going to have to overload the operator<<
function in our Institution
as described in the link posted in the other answer ( https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx?f=255&MSPPError=-2147217396 ) in order to get it to work.
You have to provide an operator <<
for your class:
std::ostream& operator << (std::ostream& os, const Institution& institution)
{
os << institution.getValue();
// ...
return os;
}
operator<<
is overloaded to allow outputting built-in types like int
and double
. But you'll need to tell the compiler how to output your class Institution
by overloading it again:
std::ostream& operator<<(std::ostream& os, const Institution& inst) {
os << inst.name(); // or something
return os;
}
There are at least two problems with the code that you have shown.
1)
for (int x = 0; x < institutions.size; x++)
std::vector::size() is a class method, a function. It is not a class member. This should read:
for (int x = 0; x < institutions.size(); x++)
2)
cout << institutions.at(x) << endl;
Unfortunately, std::ostream
knows nothing about your Institution
class. You will need to implement a class method, such as display()
, that will assemble a printable representation of the contents of the class, and write it to the output stream. So, for example, if the class contains two std::string
s, called name
, and address
:
class Institution {
// ...
public:
void display(std::ostream &o)
{
o << name << std::endl << address << std::endl;
}
// ...
};
... or, in whatever formatting style you want your class instances to be displayed. Then:
for (int x = 0; x < institutions.size(); x++)
institutions.at(x).display(std::cout);
3)
Well, here's a bonus problem with your code. It is actually written in an obsolete C++ dialect that went out of style decades ago. Whatever textbook you're using to learn C++, you need to ditch it, and pick up a textbook that was written this century, and which will teach you modern C++. In modern C++, this becomes a much more readable:
for (const auto &institution:institutions)
institution.display(std::cout);
The answers here are all correct. I will provide a slightly different answer to the displaying issue, as this is a recurring problem. What you can do is define an abstract class, we'll call it IDisplay
, which declares a pure virtual function std::ostream& display(std::ostream&) const
and declares operator<<
as a friend. Then every class that you want to be display-able must inherit from IDisplay
and consequently implement the display
member function. This approach reuses the code and is pretty elegant. Example below:
#include <iostream>
class IDisplay
{
private:
/**
* \brief Must be overridden by all derived classes
*
* The actual stream extraction processing is performed by the overriden
* member function in the derived class. This function is automatically
* invoked by friend inline std::ostream& operator<<(std::ostream& os,
* const IDisplay& rhs).
*/
virtual std::ostream& display(std::ostream& os) const = 0;
public:
/**
* \brief Default virtual destructor
*/
virtual ~IDisplay() = default;
/**
* \brief Overloads the extraction operator
*
* Delegates the work to the virtual function IDisplay::display()
*/
friend inline
std::ostream& operator<<(std::ostream& os, const IDisplay& rhs)
{
return rhs.display(os);
}
}; /* class IDisplay */
class Foo: public IDisplay
{
public:
std::ostream& display(std::ostream& os) const override
{
return os << "Foo";
}
};
class Bar: public IDisplay
{
public:
std::ostream& display(std::ostream& os) const override
{
return os << "Bar";
}
};
int main()
{
Foo foo;
Bar bar;
std::cout << foo << " " << bar;
}
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.