Why and how to overload operator<< for printing - c++

I have written a program for implementation of stack. And I have one display function in it.
This is how I wrote display function at first:
template <class t>
void Mystack<t>::display()
{
for (int i = 0; i <= top; i++)
{
std::cout << input[i] << " ";
}
}
Then I was suggested by developers to write a display function to be more generic. So I wrote display function as:
template <class T>
void Mystack<T>::display(std::ostream &os) const
{
for (int i = 0; i <= top; i++)
{
os << input[i] << " ";
}
}
As per my understanding the benefit of writing above function is that now I have a generic display function which I can use to display data to console or to a file too.
Question 1: Is my understanding correct?
Now another suggestion is to write function something like:
template <typename T>
friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d) {
d.display(s);
return s;
}
Question 2: What is the benefit of having above display function? What exactly will I be able to achieve by having above display function?

For question 1, your understanding is correct, but the real improvement comes from question 2's suggestion of writing:
template <typename T>
friend std::ostream& operator<<(std::ostream&, Mystack<T> const& );
That will let anybody stream objects of your type in the same way they would stream anything else:
std::cout << "Hi, my stack is " << stack << ", it has size " << stack.size();
to any stream they want:
some_file << "Result of computation is: " << stack;
std::cerr << "Error, invalid stack: " << stack << ", expected: " << some_other_thing;

Firstly - yes. By taking the std::ostream& parameter, you can output to any derived stream too, like std::ofstream, or std::cout, std::cerr.
Using operator<< allows you to, use that operator. Consider:
mystack<int> stackOfInts;
//...
std::cout << "Stack contents:" << std::endl << stackOfInts << std::endl;
It's just more idiomatic than a 'standard' function call.
Returning the stream allows the chaining of the operator, as in the above example. The chaining is effectively passing the result of a call to operator<< into another one:
operator<<( operator<<("Stack contents:", std::endl), stackOfInts ) );
If this overloaded call doesn't also return an std::ostream&, then there is no way to do:
operator<<( resultOfAbove, std::endl );
Declaring the function a friend allows its definition to use private members. Without this, you would have to do something like write a public getter for each private member.

Both display function are basically the same. The different is the way you call the function.
With first function, you call function in usual way:
std::cout<<"This is MyStack (with first method): ";
m.display(std::cout); //function call
std::cout<<std::endl;
With second function, you call function with operator "<<":
std::cout<<"This is MyStack (with second method): "
<<m //function call
<<std::endl;
But I personally prefer the second one. Since it's more familiar to me.

As with regard to Question 2, this is the way to go if you have a base class and lots of derived classes, and want to write operator<< only once, in the base class. Then, if you declare the display() function as virtual along your class hierarchy, you can choose at runtime the correct display function. That is, if you have something like
Derived foo;
std::cout << foo;
then Base::operator<< will call the Derived::display(), because it is marked as virtual and foo is passed by reference. This is the way to go when you have a class hierarchy and don't want to overload operator<< for each derived class.
This is a common trick in avoiding code duplication. See
Making operator<< virtual?
on StackOverflow for more details.

Related

Why is my overloaded << operator not working?

I'm trying to understand how to properly overload the "<<" operator so that I can use
std::cout << my_object;
to print useful debug messages. In particular, I need to have an implementation of << for each of my subclasses, so I'm declaring << to be virtual in the superclass.
Right now I'm stuck with the following piece of code
#include <iostream>
using namespace std;
class Shape {
public:
virtual ~Shape() { };
virtual ostream& operator<<(std::ostream &strm) = 0;
};
class Square : public Shape {
int size;
public:
Square() { size = 10; }
~Square() { }
ostream& operator<<(std::ostream &strm) {
return strm << "a square with size " << size;
}
};
int main() {
Square *my_square = new Square();
cout << "my_square is " << my_square << "\n";
}
which (I think) should be working, but doesn't. What I get when using "<<" is that the pointer value of my_square gets printed, rather than the result of the overloaded << .
$ ./a.out
my_square is 0xcacc20
What am I missing here?
operator<< can't be a member function. This is because of the order of the arguments. The stream has to come first.
When calling an overloaded operator, such as:
os << object;
the compiler will attempt to look up both
os.operator<<(object);
and
operator<<(os, object);
(The rules for this can be rather complex, I won't attempt to describe them here.)
Because the stream always comes on the left, your member function will never be found, since it would have to be called as:
object.operator<<(os);
You need to write a free function like:
ostream& operator<<(std::ostream &strm, Square const& square) {
return strm << "a square with size " << square.size();
}
(where Square::size() returns the size member).
Then you need to remember to dereference your pointer too:
std::cout << *my_square << '\n';
Although I see no reason to be dynamically allocating my_square in this example anyway. Just stick it on the stack as a local variable.
If the aim here is ultimately to be able to print any Shape&, and have the printed output follow the "real" type, you would need to create:
virtual std::ostream& print(std::ostream&) const = 0;
in the Shape base class, and override it in each derived class, then have a free function:
std::ostream& operator<<(std::ostream& os, Shape const& shape)
{
return shape.print(os);
}
It is often advised to make all binary operators on your type non-member functions, so that both arguments are treated equally, and the operation remains commutative. See Scott Meyers, Effective C++ (3rd Edition), Item 24, (or find a summary online).
As noted by others, the problem is that operator << can't be member function (because of the order of arguments). The canonical way to do this is to have operator <<(const Shape&) call a virtual function in Shape
class Shape {
friend ostream& operator<<(std::ostream& str, const Shape& shape);
virtual void do_print(ostream& str) = 0;
public:
virtual ~Shape() { };
};
ostream& operator<<(std::ostream& str, const Shape& shape) {
shape.do_print(str);
return str;
}
Note that it is legal to have do_print be private, even though it is going to be (must be) overridden by derived classes. You could make it protected though if you like.
What am I missing here?
You have created operator which will get you class as a first argument and stream as the second.
my_square << std::cout;
I'd create free function and to make it dynamic I'd call some virtual method in it

Operator << in a user defined method

I was trying to write a method that would take parameters using the >> operator as parameters similar to std::cin but I don't know how. Is it possible to create this kind of method that would take this stream like parameter, convert it properly (for example convert all ints to strings etc) and then save to an std::string variable?
Here is an example of how I would like to run the function:
int i = 0;
myMethod << "some text" << i << "moar text";
Inside that method I would like to take those parameters and store in a string.
Edit
I will try to explain exactly what this application is about: I Am trying to make a Clogger singleton class which will be used to save logs to a file. With this construction, I can call *CLogger::instance() << "log stuff"; from anywhere in the code and that's OK. Thanks to answers from this topic I have come to this. The problem is that each operator<< I use, then the object is going to be called. So if I do *CLogger::instance() << "log stuff " << " more stuff " << " even more";` this method(?) is going to be called 3 times:
template<typename T>
CLogger& operator<<(const T& t)
{
...
return *this;
}
That's not good for me as I intend to add some text before and after each log line. For example I would always like to add time before and std::endl after. Following the example I gave instead of getting:
[00:00] log stuff more stuff even more
I would get:
[00:00] log stuff
[00:00] more stuff
[00:00] even more
So I made an attempt to remove this behaviour by changing the method like this:
template<typename T>
CLogger& operator<<(const T& t)
{
ostringstream stream;
stream << t;
m_catString += stream.str();
if (stream.str() == "\n")
{
push_back(m_catString);
m_catString.clear();
}
return *this;
}
This way the program knows when to push new log line if I add "\n" at the end. Its nearly ok, as I bet I will forget to add this. Is there any more clever way?
You can't pass parameters to a method using <<, you need an object.
Something like this:
struct A
{
template<typename T>
A& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
data += stream.str();
return *this;
}
std::string data;
};
// ...
A a;
a << "Hello " << 34 << " World";
std::cout << a.data;
Regarding your update:
The most obvious thing is to implement the operator in CLogger instead and get rid of the Pusher class; that would let you write *CLogger::instance() << "sample text" << 10;
If you can't do that for some reason (you're giving out information piecemeal, so it's hard to tell), you can declare Pusher a friend and use the same method as everywhere else:
struct Pusher
{
template<typename T>
Pusher& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
CLogger::instance()->push_back(stream.str());
return *this;
}
};
The only way I know is creating a class class Method and then overload the operator<<, operators overloading
template<class T>
Method &operator<<(const T &x)
{
// Do whatever you like
return *this;
}
Then you can use it like :
Method myMethod;
myMethod << ... ;
you can look at this question about creating a cout-like class
std::cin and std::cout are not functions by the way
EDIT
class CLogger
{
...
template<typename T>
CLogger& operator<<(const T& t)
{
push_back(std::to_string(t));
return *this;
}
};
You don't have to create a class Pusher, just overload the operator in your first class, now you can use it with your object :
myCLogger << t; // this would call the function push back

<< operator overloading in C++ for logging purposes

I have a C++ class where I place many std::cout statements to print informative text messages about a mass of signals that this class is handling. My intentition is to redirect these text messages to a function named log. In this function, I have flag named mVerbose which defines if the log text should be printed. The content of this function is as follows:
void XXXProxy::log(std::stringstream& ss)
{
if(mVerbose)
{
std::cout << ss;
ss << "";
}
}
Then, the caller code snippet to this function is as follows:
std::stringstream logStr;
logStr << "SE"
<< getAddr().toString()
<< ": WAITING on epoll..."
<< std::endl;
log(logStr);
I would like to overload the << operator in my XXXProxy in a way that I can get rid of creating a std::stringstream object and calling the log function. I want to be able to log the text messages as below and let the << operator aggregate everything into:
<< "SE"
<< getAddr().toString()
<< ": WAITING on epoll..."
<< std::endl;
So I wouldlike to have an member << function that looks like:
void XXXProxy::operator << (std::stringstream& ss)
{
if(mVerbose)
{
std::cout << ss;
ss << "";
}
}
QUESTION
I am relatively a novice C++ developer and get lots of compilation errors when attemting to write the above stated like << operator. Could you please make some suggestions or direct me to some links for me to correctly implement this << operator. Thanks.
If you don't want to use std::cout directly and you want to have your own Log class, you could implement a simple wrapper providing the same interface of std::ostream: operator<<:
class Log {
private:
std::ostream& _out_stream;
//Constructor: User provides custom output stream, or uses default (std::cout).
public: Log(std::ostream& stream = std::cout): _out_stream(stream) {}
//Implicit conversion to std::ostream
operator std::ostream() {
return _out_stream;
}
//Templated operator>> that uses the std::ostream: Everything that has defined
//an operator<< for the std::ostream (Everithing "printable" with std::cout
//and its colleages) can use this function.
template<typename T>
Log& operator<< (const T& data)
{
_out_stream << data;
}
}
So if you implement std::ostream& operator>>(std::ostream& os , const YourClass& object) for your classes, you can use this Log class.
The advantage of this approach is that you use the same mechanism to make std::cout << your_class_object work, and to make the class work with the Log.
Example:
struct Foo
{
int x = 0; //You marked your question as C++11, so in class initializers
//are allowed.
//std::ostream::operator<< overload for Foo:
friend std::ostream& operator<<(std::ostream& os , const Foo& foo)
{
os << foo.x;
}
};
int main()
{
Log my_log;
Foo my_foo;
my_foo.x = 31415;
my_log << my_foo << std::endl; //This prints "31415" using std::cout.
}
Possible improvements:
You could write a extern const of class Log, and make the class implement a singleton. This allows you to access the Log everywhere in your program.
It's common in log outputs to have a header, like Log output (17:57): log message. To do that, you could use std::endl as a sentinel and store a flag that says when the next output is the beginning of a line (the beginning of a log message). Checkout the next answer for a complete and working implementation.
References:
std::ostream
operator<< for std::ostream
std::enable_if
std::is_same
decltype specifier
The timestamp of the example was only that, an example :).
But if you like that, we could try to implement it. Thankfully to C++11 and its STL's big improvements, we have an excellent time/date API: std::chrono
std::chronois based in three aspects:
Clocks
Durations
Time points
Also, chrono provides three types of clocks, std::system_clock, std::steady_clock , and std::high_resolution_clock. In our case, we use std::system_clock (We want access to the date-time, not meassuring precise time intervals).
For more info about std::chrono, checkout this awsome Bo Qian's youtube tutorial.
So if we have to implement a time stamp for our log header, we could do this:
EDIT: Like other good things, C++ templates are good tools until you overuse it.
Our problem was that std::endl is a templated function, so we cannot pass it directly to
annother templated function as parammeter (operator<< in our case), because the compiler cannot deduce std::endl template argumments directly. Thats the recurrent error "unresolved overloaded function type".
But there is a much simpler way to do this: Using an explicit overload of operator<< for std::endl only, and other templated for everything else:
class Log
{
private:
std::ostream& _out_stream;
bool _next_is_begin;
const std::string _log_header;
using endl_type = decltype( std::endl ); //This is the key: std::endl is a template function, and this is the signature of that function (For std::ostream).
public:
static const std::string default_log_header;
//Constructor: User passes a custom log header and output stream, or uses defaults.
Log(const std::string& log_header = default_log_header , std::ostream& out_stream = std::cout) : _log_header( log_header ) , _out_stream( out_stream ) , _next_is_begin( true ) {}
//Overload for std::endl only:
Log& operator<<(endl_type endl)
{
_next_is_begin = true;
_out_stream << endl;
return *this;
}
//Overload for anything else:
template<typename T>
Log& operator<< (const T& data)
{
auto now = std::chrono::system_clock::now();
auto now_time_t = std::chrono::system_clock::to_time_t( now ); //Uhhg, C APIs...
auto now_tm = std::localtime( &now_time_t ); //More uhhg, C style...
if( _next_is_begin )
_out_stream << _log_header << "(" << now_tm->tm_hour << ":" << now_tm->tm_min << ":" << now_tm->tm_sec << "): " << data;
else
_out_stream << data;
_next_is_begin = false;
return *this;
}
};
const std::string Log::default_log_header = "Log entry";
This code snippet works perfectly. I have pushed the complete implementation to my github account.
Reference:
std::chrono
std::chrono::system_clock
std::chrono::system_clock::now()
std::time_t
std::chrono::system_clock::to_time_t()
std::tm
std::localtime()

What is the use of declaring a function which takes and return "ostream&" rather than overloading operator<<?

I've come across functions that, rather than overloading the operator << to use with cout, declare a function that takes an ostream and returns an ostream
Example:
#include <iostream>
class A {
private:
int number;
public:
A(int n) : number(n) {}
~A() {}
std::ostream& print(std::ostream& os) const;
friend std::ostream& operator<<(std::ostream& os, const A a);
};
An example of implementation:
std::ostream& A::print(std::ostream& os) const {
os << "number " << number;
return os;
}
std::ostream& operator<<(std::ostream& os, const A a) {
os << "number " << a.number;
return os;
}
Now if I run this I can use the different functions in different situations.. E.g.
int main() {
A a(1);
std::cout << "Object."; a.print(std::cout);
std::cout << "\n\n";
std::cout << "Object." << a;
std::cout << "\n\n";
return 0;
}
Output:
Object.number 1
Object.number 1
There doesn't seem to be a situation where the print function would be needed since you could only use separately or in the beginning of a "cout chain" but never in the middle or end of it which perhaps makes it useless. Wouldn't it (if no other use is found) be better off using a function "void print()" instead?
It would make sense where an inheritance hierarchy comes in to play. You can make the print method virtual, and in the operator for the base class, delegate to the virtual method to print.
It would make a lot more sense if operator<<() actually looked like
std::ostream& operator<<(std::ostream& os, const A a) {
return a.print(os);
}
Then operator<<() wouldn't need to be a friend.
A function that can be used as the start of a cout chain certainly sounds more useful than one that can't, all other things being equal.
I've implemented several functions with signatures like you describe because operator<< is only one name, and sometimes I need to have objects streamed in multiple different ways. I have one format for printing to the screen, and another format for saving to a file. Using << for both would be non-trivial, but choosing a human-readable name for at least one of the operations is easy.
The use of operator<< assumes that there is only one sensible way to print data. And sometimes that is true. But sometimes there are multiple valid ways to want to output data:
#include <iostream>
using std::cout; using std::endl;
int main()
{
const char* strPtr = "what's my address?";
const void* address = strPtr;
// When you stream a pointer, you get the address:
cout << "Address: " << address << endl;
// Except when you don't:
cout << "Not the address: " << strPtr << endl;
}
http://codepad.org/ip3OqvYq
In this case, you can either chose one of the ways as the way, and have other functions (print?) for the rest. Or you can just use print for all of them. (Or you might use stream flags to trigger which behavior you want, but that's harder to set up and use consistently.)

std::endl is of unknown type when overloading operator<<

I overloaded operator <<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
Works but:
my_stream << endl;
Gives compilation error:
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'UIStream' (or there is no acceptable conversion)
What is the work around for making my_stream << endl work?
std::endl is a function and std::cout utilizes it by implementing operator<< to take a function pointer with the same signature as std::endl.
In there, it calls the function, and forwards the return value.
Here is a code example:
#include <iostream>
struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;
return *this;
}
// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);
// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}
// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;
// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;
return stream;
}
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);
return *this;
}
};
int main(void)
{
MyStream stream;
stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;
return 0;
}
Hopefully this gives you a better idea of how these things work.
The problem is that std::endl is a function template, as your operator <<
is. So when you write:
my_stream << endl;
you'll like the compiler to deduce the template parameters for the operator
as well as for endl. This isn't possible.
So you have to write additional, non template, overloads of operator << to
work with manipulators. Their prototype will look like:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(there are two others, replacing std::ostream by std::basic_ios<char> and
std::ios_base, which you have also to provide if you want to allow all
manipulators) and their implementation will be very similar to the one of
your templates. In fact, so similar that you can use your template for
implementation like this:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
return operator<< <ostream_manipulator> (os, pf);
}
A final note, often writing a custom streambuf is often a better way to
achieve what one try to achieve applying to technique you are using.
I did this to solve my problem, here is part of my code:
template<typename T>
CFileLogger &operator <<(const T value)
{
(*this).logFile << value;
return *this;
}
CFileLogger &operator <<(std::ostream& (*os)(std::ostream&))
{
(*this).logFile << os;
return *this;
}
Main.cpp
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
I got the reference in here http://www.cplusplus.com/forum/general/49590/
Hope this can help someone.
See here for better ways of extending IOStreams. (A bit outdated, and tailored for VC 6, so you will have to take it with a grain of salt)
The point is that to make functors work (and endl, which both outputs "\n" and flushes is a functor) you need to implement the full ostream interface.
The std streams are not designed to be subclassed as they have no virtual methods so I don't think you'll get too far with that. You can try aggregating a std::ostream to do the work though.
To make endl work you need to implement a version of operator<< that takes a pointer-to-function as that is how the manipulators such as endl are handled i.e.
UStream& operator<<( UStream&, UStream& (*f)( UStream& ) );
or
UStream& UStream::operator<<( UStream& (*f)( UStream& ) );
Now std::endl is a function that takes and returns a reference to a std::basic_ostream so that won't work directly with your stream so you'll need to make your own version which calls through to the std::endl version in your aggregated std::iostream.
Edit: Looks likes GMan's answer is better. He gets std::endl working too!
In addition to the accepted answer, with C++11 it is possible to overload operator<< for the type:
decltype(std::endl<char, std::char_traits<char>>)