I have the following class template which will accept both primitives and object. However like this I can only print primitives. How can I make it function using both primitives and objects? Thanks
template<class T>
class A
{
private:
vector <T> l;
public:
void print() const
{
for (int i=0;i<.size();i++)
{
cout<<l[i]<<endl; //error here
}
}
};
The reason why you can print primitives is that <iostream> provides overloads for operator<< for them.
To let your template print your classes in the same way, you need to define your own implementation of the operator:
// This implementation puts operator << outside your class.
// Mark it "friend" in MyClass if it needs access to private members of MyClass.
ostream& operator<<(ostream& ostr, const MyClass& myClass) {
// Do the printing based on the members of your class
ostr << myClass.member1 << ":" << myClass.member2;
return ostr;
}
The compiler will detect this operator during template expansion, and use it for printing when you do this:
cout<<l[i]<<endl;
You can put operator<< inside your class as well:
ostream &operator<<(ostream &os) {
ostr << member1 << ":" << member2;
}
I am assuming that here, you want to print an object instead of a variable belonging to a fundamental datatype.
For such cases, you can look at operator overloading in C++(more specifically overloading insertion operator).
For more information about overloading the insertion operator for an object, you can visit this URL
http://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx
Given below is an example about how to go about it
ostream& operator<<(ostream& os, const Datatype& dt)
{
os << dt.a <<" " << dt.b;
return os;
}
Here Datatype is the name of the class and a and b are two private members of a and b which will be printed when you try to print the object.
However, to overload using this technique, do not forget to make this function as a friend function of the class(as given below) as the function requires access the to private members of the class.
friend ostream& operator<<(ostream& os, const Datatype& dt);
Related
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::strings, 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;
}
Live on Coliru
I've found myself in a bit of trouble trying to overload operator<< correctly. I've searched around other questions about it, but none of the answers seemed to fit this one, so here it is:
I have a class (Register) that stores specimens of another class(subclasses of Film, which is abstract). The overloaded operator << for Register should put all the data stored in each Film type element on screen through the ostream class.Here's the code:
class Register{
private:
int elementNum;
Film* pData;
};
ostream &operator<<(ostream & os,const Register &v);
These are in the header, operator << in the cpp:
ostream &operator<<(ostream & os,const Register &v){
for(int i=0;i<v.elementNum;i++){
os<<v.pData[i].print()<<endl;
}
return os;
}
Problem is, this way i cannot access the private variables of Register. So I tried putting the overaloaded operator<< as a member of Register, but then the compiler tells me the function must take only one argument. Last, if I remove ostream& os from the parameters, it tells me the function needs two arguments. So i would be interested in a solution where the information stored in pData can be put on screen efficiently with operator <<. Thanks in advance!
You have to declare operator<< as a friend if access to Register implementation (private data) has to be granted:
class Register{
private:
//...
friend std::ostream &operator<<( std::ostream & os,const Register &v);
};
std::ostream &operator<<( std::ostream & os,const Register &v) {
for( int i=0; i<v.elementNum; i++){
os << v.pData[i].print() << std::endl;
}
return os;
}
Friend function has access to all private ( as well as protected and public) data of a class that declared a friend.
C++ Standard n3337 § 11.3/1 says
Friends
A friend of a class is a function or class that is given permission to
use the private and protected member names from the class. A class
specifies its friends, if any, by way of friend declarations. Such
declarations give special access rights to the friends, but they do
not make the nominated friends members of the befriending class.
§ 11.3/2
Declaring a class to be a friend implies that the names of private and
protected members from the class granting friendship can be accessed
in the base-specifiers and member declarations of the befriended
class.
Make your operator<< a friend of the class. You can read it up here.
You could make operator<< a friend of class Register see code below:
class Register{
private:
friend ostream &operator<<(ostream & os,const Register &v);
int elementNum;
Film* pData;
};
Thus, operator<< will have access to class Register private members.
To access the private members of Register, make operator<< a friend function:
class Register{
private:
int elementNum;
Film* pData;
friend ostream &operator<<(ostream & os,const Register &v);
};
I implemented the OS-Operator in a project like this:
XYZ.h file
friend std::ostream& operator<<(std::ostream& os, const Liwanze& arg);
XYZ.cpp file
std::ostream& operator<<(std::ostream& os, const Liwanze& arg) {
string area = "";
if (arg.loc == 1)
area = "Buxtehude";
if (arg.loc == 2)
area = "Bangladesch";
if (arg.loc == 3)
area = "Zimbabwe";
if (arg.loc == 4)
area = "Bronx";
os << arg.name << " [" << area << "] ";
return os;
}
or if you wish to avoid polluting your class with unwanted friends, defer the formatting to a public member of Register.
class Register{
public:
void writeTo(std::ostream& os) const {
for( int i=0; i<elementNum; i++){
os << pData[i].print() << std::endl;
}
}
private:
//...
};
std::ostream &operator<<( std::ostream & os,const Register &v) {
v.writeTo(os);
return os;
}
If you make the writeTo function defer to a protected virtual function, then operator<< will work on anything derived from Register, even in a multi-threaded environment.
class Register{
public:
// public non-polymorphic interface...
void writeTo(std::ostream& os) const {
os << "any header information\n" << endl;
std::lock_guard<std::mutex> myLock(_myInternalMutex); // in MT environment
handleWriteTo(os); // defer to protected polymorphic implementation
}
protected:
virtual void handleWriteTo(std::ostream& os) const {
for( int i=0; i<elementNum; i++){
os << pData[i].print() << std::endl;
}
}
private:
//...
};
std::ostream &operator<<( std::ostream & os,const Register &v) {
v.writeTo(os);
return os;
}
I have a class Counter and I want to overload operator << to output the data member of Counter. I tried to make the ostream overloading a member function:
Counter{
public:
std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
int count_;
};
std::ostream& Counter::operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count_;
return outStream;
}
But the g++ compiler always outputs the same error:
‘std::ostream& Counter::operator<<(std::ostream&, const Counter&)’ must take exactly one argument
However, if I changed the overloading function to be a friend of the class, it worked all well, like this:
Counter{
public:
friend std::ostream& operator<<(std::ostream& outStream, const Counter& c);
private:
int count_;
};
std::ostream& operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count_;
return outStream;
}
Does this mean that the the stream operator overloading cannot be a member function of a class?
Add a public query method that returns the value of count_, then it does not have to be a friend:
Counter{
public:
int count() const { return count_; }
private:
int count_;
};
std::ostream& operator<<(std::ostream& outStream, const Counter& c){
outStream << c.count();
return outStream;
}
If you put the ostream operator in the class itself then it will not work the way you expect it to. It would be a member function meaning to invoke it one would have to do this: c.operator<<("output") which is obviously not what you mean to do. For it to work as you expect an ostream operator it must be outside the class. You can do this by making it a friend or just put it outside of the class and use getters (accessors) to output the data.
It doesn't have to be a friend, but it can't be a member. Member operators only work when they are inside the class which corresponds to the left-hand operand.
Unfortunately the useful overloads for the streaming output operators ( << ) cannot be class members, because the ostream& must be on the left in use and declaration. They do not need to be friends of the class you wish to stream unless they need access to protected or private members. This means that if you can implement a streaming operator using just public functions such as observers/accessors without declaring it a friend.
In your first Counter class you are declaring a member function of the class that does not seem valid. In the second example of the Counter class you are stating that your operator overload for << , which seems valid, has access to the private members. In the second example the function must still be declared outside the class.
Wikipedia Operators in C and C++ has a good list of possible operator overloads, including the in class << overloads even though they are not very useful. The in class overloads must be called backwards CounterInstance << cout; which is counterintuitive.
In a project I'm working on, I have a Score class, defined below in score.h. I am trying to overload it so, when a << operation is performed on it, _points + " " + _name is printed.
Here's what I tried to do:
ostream & Score::operator<< (ostream & os, Score right)
{
os << right.getPoints() << " " << right.scoreGetName();
return os;
}
Here are the errors returned:
score.h(30) : error C2804: binary 'operator <<' has too many parameters
(This error appears 4 times, actually)
I managed to get it working by declaring the overload as a friend function:
friend ostream & operator<< (ostream & os, Score right);
And removing the Score:: from the function declaration in score.cpp (effectively not declaring it as a member).
Why does this work, yet the former piece of code doesn't?
Thanks for your time!
EDIT
I deleted all mentions to the overload on the header file... yet I get the following (and only) error. binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion)
How come my test, in main(), can't find the appropriate overload? (it's not the includes, I checked)
Below is the full score.h
#ifndef SCORE_H_
#define SCORE_H_
#include <string>
#include <iostream>
#include <iostream>
using std::string;
using std::ostream;
class Score
{
public:
Score(string name);
Score();
virtual ~Score();
void addPoints(int n);
string scoreGetName() const;
int getPoints() const;
void scoreSetName(string name);
bool operator>(const Score right) const;
private:
string _name;
int _points;
};
#endif
Note: You might want to look at the operator overloading FAQ.
Binary operators can either be members of their left-hand argument's class or free functions. (Some operators, like assignment, must be members.) Since the stream operators' left-hand argument is a stream, stream operators either have to be members of the stream class or free functions. The canonical way to implement operator<< for any type is this:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// stream obj's data into os
return os;
}
Note that it is not a member function. Also note that it takes the object to stream per const reference. That's because you don't want to copy the object in order to stream it and you don't want the streaming to alter it either.
Sometimes you want to stream objects whose internals are not accessible through their class' public interface, so the operator can't get at them. Then you have two choices: Either put a public member into the class which does the streaming
class T {
public:
void stream_to(std::ostream&) const {os << obj.data_;}
private:
int data_;
};
and call that from the operator:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
obj.stream_to(os);
return os;
}
or make the operator a friend
class T {
public:
friend std::ostream& operator<<(std::ostream&, const T&);
private:
int data_;
};
so that it can access the class' private parts:
inline std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << obj.data_;
return os;
}
Let's say you wanted to write an operator overload for + so you could add two Score objects to each other, and another so you could add an int to a Score, and a third so you could add a Score to an int. The ones where a Score is the first parameter can be member functions of Score. But the one where an int is the first parameter can't become member functions of int, right? To help you with that, you're allowed to write them as free functions. That is what is happening with this << operator, you can't add a member function to ostream so you write a free function. That's what it means when you take away the Score:: part.
Now why does it have to be a friend? It doesn't. You're only calling public methods (getPoints and scoreGetName). You see lots of friend operators because they like to talk directly to the private variables. It's ok by me to do that, because they are written and maintained by the person maintaing the class. Just don't get the friend part muddled up with the member-function-vs-free-function part.
You're getting compilation errors when operator<< is a member function in the example because you're creating an operator<< that takes a Score as the first parameter (the object the method's being called on), and then giving it an extra parameter at the end.
When you're calling a binary operator that's declared as a member function, the left side of the expression is the object the method's being called on. e.g. a + b might works like this:
A a;
B b
a.operator+(b)
It's typically preferable to use non-member binary operators (and in some cases -- e.g. operator<<for ostream is the only way to do it. In that case, a + b might work like this:
A a;
B b
operator+(a, b);
Here's a full example showing both ways of doing it; main() will output '55' three times:
#include <iostream>
struct B
{
B(int b) : value(b) {}
int value;
};
struct A
{
A(int a) : value(a) {}
int value;
int operator+(const B& b)
{
return this->value + b.value;
}
};
int operator+(const A& a, const B& b)
{
return a.value + b.value;
}
int main(int argc, char** argv)
{
A a(22);
B b(33);
std::cout << a + b << std::endl;
std::cout << operator+(a, b) << std::endl;
std::cout << a.operator+(b) << std::endl;
return 0;
}
Im really unsure how to call the function:
friend ostream& operator<<(ostream& out, stack::myItem& theItem);
that is public to my stack object:
class stack
{
public:
stack(int capacity);
~stack(void);
void method1();
...
private:
struct myItem
{
int item;
};
...
public:
friend ostream& operator<<(ostream& out, stack& s);
friend ostream& operator<<(ostream& out, stack::myItem& theItem);
};
It's no different than using stream operator << for any other type (it is called operator overloading for a reason).
However, outputting should not modify an object, hence you really should pass it by const reference (otherwise calls with temporaries would fail to compile).
friend ostream& operator<<(ostream& out, const stack& s);
friend ostream& operator<<(ostream& out, const stack::myItem& theItem);
This operator is a classic binary operator.
// Say I have an operator declared like this:
return_type operator#(left_type lhs, right_type rhs);
// Then the invocation is done this way:
left_type L;
right_type R;
return_type result = L # R;
In the case of the streaming operator, it is a bit special since the left hand argument and the return type actually have the same type (and indeed, will refer to the same object, albeit at different times). This has been done to allow chaining.
// Chaining
std::cout << "<Output> " << 1 << std::endl;
// Which can be analyzed like such
operator<<(
operator<<(
operator<<(
std::cout ,
"<Output> "
),
1
),
std::endl
);
As you can see, the syntax merely allows a convenient invocation. One might note that the order is very well defined, it is a strict left to right evaluation.
So with your object, it would become:
stack s;
std::cout << s << std::endl;
Just like that!
Call it from where? As it's coded only the class knows about the private struct. No code external to the class could use that method since it couldn't create an instance of the struct. Marking it as friend doesn't do you much good.