i need someone who explain me these lines of code part by part and i need some help in using "ostream" with simple examples. thank you :).
inline std::ostream& operator<<(std::ostream& os, const Telegram& t)
{
os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
return os;
}
UPDATE 1: when i use this function it doesnt compile and the error says:
std::ostream& class::operator<<(std::ostream& os, const Telegram& t) must take exactly one argument
These line are simply adding the ability to handle Telegram objects to the standard output stream class.
When you add a new class and you want output streams like cout to intelligently handle them, you need to add a new << operator method which has the new object type as the second argument.
What the code above is doing is exactly that. When you later execute the statements:
Telegram tg("Bob", "Hello, how are you?");
cout << tg;
that function in your question will be called with the stream as the first argument and your tg object as the second argument and it will then be able to output the data in a format suitable to the class.
This was actually one of the early C++ things I had trouble getting my head around. Although the class is supposed to be self-contained, you're actually adding something to a different class to handle the output. Once you understand why this is happening (because it's the ostream class that is responsible for outputting things rather than your own class), it will hopefully make sense.
Hopefully making it clearer with a simpler example:
1 inline std::ostream& operator<<(std::ostream& os, const Telegram& t) {
2 os << "message: " << t.Msg;
3 return os;
4 }
Line 1 is simply the function definition. It allows you to return the stream itself (that you pass in) so you can chain << segments. The operator<< is simply the function you're providing, which is the one called when you put << tg into an output stream statement.
Line 2 uses more basic << statements that have already been defined (in this case, whatever type Msg is, probably a string).
Then line 3 returns the stream, again to allow chaining of << segments.
The basic idea is to provide operator<< functions that build on existing operator<< function for the data types that constitute your type.
And with a simple wrapper class containing just an int:
#include <iostream>
// This is my simple class.
class intWrapper {
public:
intWrapper (int x) { myInt = x; };
int getInt (void) { return myInt; }
private:
int myInt;
// Must be friend to access private members.
friend std::ostream& operator<< (std::ostream&, const intWrapper&);
};
// The actual output function.
inline std::ostream& operator<< (std::ostream& os, const intWrapper& t) {
os << "int: " << t.myInt;
return os;
}
// Main program for testing.
// Output with getter and with ostream.
int main (void) {
class intWrapper x(7);
std::cout << x.getInt() << std::endl; // ostream already knows about int.
std::cout << x << std::endl; // And also intWrapper, due to the
// function declared above.
return 0;
}
This outputs:
7
int: 7
the first by just calling the getter function to retrieve the integer, the second by calling the << operator function we added to ostream.
The function you posted (henceforth "the function") is an overload of the insertion operator, operator <<. It allows you to output an object of type Telegram, or any other type deriving from Telegram or convertible to a Telegram, to an output stream. This is similar in spirit to the common use of IO streams in C++:
std::cout << 0 << '\n';
Here you output the int 0 followed by the char newline to the standard output stream. With the function you posted you can now do something like
Telegram tel; // if Telegram has a default constructor
std::cout << tel << '\n';
something you would otherwise not been able to do, because the standard C++ library doesn't know about your new Telegram type and so never defined how to output objects of this type.
In code:
inline std::ostream& operator<<(std::ostream& os, const Telegram& t)
The first line starts with the inline keyword. Presumably the function is defined in a header file, and so in that case you must use the inline keyword so the definition does not violate the one definition rule.
That is, every time you include the header in an implementation file you get the function defined for that implementation file. When the linker comes in to link together all the compiled object files it will find multiple definitions of the function, one in each implementation file that included the header with the function you posted. This is something C++ forbids; C++ demands a function may be implemented no more than one time, and exactly one time if you intend to call it.
The use of the inline keyword essentially asks the C++ compiler to make sure that function is not defined more than once in such a way that the linker jumps off its seat and complains about the ambiguity of multiple definitions to choose from.
Here I argue it's a bad idea to inline the function. It would be a better idea to remove the inline keyword and move the function definition to its own translation unit, or implementation file. This way the function will compile exactly once, as opposed to once for each implementation file that includes the header with the function.
Next you will notice that function is a free function, as opposed to a member function. This allows (requires, as a matter of fact) the function to specify the operator's left operand, the stream object. This means the function will work with any object that is convertible to a stream. It also means you don't need to modify a class to add this extension to output semantics. If the function would be a member then you'd have to change the header of the class, which in turns means recompiling all implementation files that include that header. Granted, it appears your function is defined in a header; that's probably a bad idea, as I explained above.
Next you see that the function returns a std::ostream. std::ostream is in fact typedef'd as std::basic_ostream<char, std::char_traits<char> >, and therefore your function can only output Telegram objects to streams that work on char types.
The reason the function returns a std::ostream is so that you can chain calls to the function. If you look carefully,
std::cout << 0 << 1;
is in fact a chain of two calls to the insertion operator overload function. Once to output 0, and then to output 1. It is equivalent to
std::operator<<(std::operator<<(std::cout, 0), 1);
The first call to insert 0 returns an output stream, and the second call to insert 1 takes that returned output stream and inserts into that 1. That's why we return the output stream: so we can chain calls.
You will also note that the insertion operator has a left-to-right associativity, which means that in the above statement 0 is guaranteed to be output first, and 1 second. This as opposed to the equivalent line I wrote above, in which the associativity (of function calls) is inside-out. This yields a much less readable code IMO, and that's one of the benefits of using operator << for output semantics.
Next look at the function's parameters. The first parameter, a std::ostream, is taken by reference. This so you can change the stream. That's also why the stream is not taken by const reference.
The second parameter can be taken by const reference, because we don't want to change it, just read it. However, we do want to take it by reference, again because we don't intend to change it, not even for a local purpose, and so saving the construction of a copy can only be a good idea. It also allows for accepting derivatives of Telegram and caling virtual functions upon them, should the need arise. Also, taking a const reference allows you to output a temporary, as in std::cout << Telegram() << '\n';.
{
os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
This code should be self explanatory now. Presumably each of the members you insert into the output stream has the insertion operator defined for. The standard library defines insertion into output streams for primitives, for strings, for complex numbers and other standard types.
return os;
}
And finally you return the stream object, so the caller can chain the output with outputting another object. Note that you could simply return the result of the chain:
return os << "time: " << t.DispatchTime << " Sender: " << t.Sender
<< " Receiver: " << t.Receiver << " Msg: " << t.Msg;
Finally, to demonstrate the bonus you get from the use of a free function and taking the Telegram parameter by reference, consider:
struct Telegram {
Telegram();
Telegram(const Communication& c);
virtual ~Telegram();
};
struct Message : public Telegram {
};
struct Letter {
operator Telegram() const;
};
// ...
Telegram t;
Communication c;
Message m;
Letter l;
std::cout << t << '\n'
<< c << '\n'
<< m << '\n'
<< l << '\n';
All using that single function for outputting a Telegram object.
Related
q1.
All inserter functions have this general form:
ostream &operator<<(ostream &stream,class_type obj){
//body of inserter
return stream;
}
The first parameter to the function is a reference to the output stream. So,my question is Can i make that parameter an object of ostream i.e
Is this definition valid?
ostream &operator<<(ostream stream,class_type obj) //Can i create a parameter of stream object here
How can i make the parameter a stream object rather than a reference to a stream?
q2.
Can you please explain why insertors and extractors are required to return a ref to a stream. (An example would be very helpful!)
Thanks!
1: No, you can't make it an object (i.e. passed by value) as the operator needs to act on the original stream. If you pass the object in, it will create a copy, act on that and then discard it at the end of the function.
2: They need to return a reference to a stream (not just any stream, but the same stream that was passed as a parameter) in order to enable this:
cout << "Multiple " << "outputs";
If you didn't return the reference, the next << operator in the chain wouldn't also be able to act on the same stream as you wouldn't have returned it.
You can do whatever you like: take a stream by value, take something else than a stream, return by copy, don't return anything, or return any kind of object you like. But... you won't get the behavior you expect for working with streams.
The correct way of looking to this is: first know what syntax you are trying to enable and what its behavior should be and then understand why things have to be done in a certain way in order for that syntax to work that way.
So. What you are trying to enable is this. Let's say you have a custom class X and you decide to make it to work with output stream. This means you want the following to work:
cout << x;
cout << x << x;
cout << x << " test ";
cout << " test " << x << " test ";
// etc
For all of those to work as intended you need to have operator<< take a std::ostream by reference and return a reference to the same ostream object.
I have a main function that prints a sudoku game to the console as I play. I call a print board method which outputs the board along with a 2D array with the numbers. I've been modifying the game to output to the file after every cout:
cout << "puzzle created" << endl;
output << "puzzle created" << endl;
Then the problem is that there is an error when I try the same with a method:
sudoku.printBoard(); //method to print board to console
I can't simply say:
output << sudoku.printBoard();
and I can't say:
output << "number";
in the method in the board.cpp file either.
Does anyone know any way around this?
This is the problem with print() member functions, and the reason you shouldn't write them. At least, not like this. You've locked yourself into printing to stdout, and now that you want to print somewhere else instead, you're stuck.
Instead, have a function that prints where you tell it to. This may be stdout or a file or whatever.
The function will be declared like this:
void printBoard(std::ostream& os);
and inside its definition, you will use os rather than std::cout.
Then your code will look like this:
sudoku.printBoard(std::cout);
sudoku.printBoard(output);
It works because both std::cout and output are of types that derive from std::ostream.
If you need the cout variant a lot, and you don't want to provide the argument every time because it's getting messy, simply provide an overload:
void printBoard()
{
printBoard(std::cout);
}
Now you can still write:
sudoku.printBoard();
Whether this is more or less confusing for developers on your project is for you to decide.
If you don't have other things to print, so that this is the only function of its kind within the type of sudoku, a more idiomatic approach would be to create an operator<< for that type:
std::ostream& operator<<(std::ostream& os, const SudokuBoard& board)
{
board.printBoard(os);
return os;
}
Now you can use it like this:
std::cout << sudoku;
output << sudoku;
Make a class that takes two ostreams in the constructor. One of these can be std::cout. Store these in the class as references.
Create output stream operators (<<) and use those to write to the two streams.
To use this in other classes pass it as a reference in their constructor (look up dependency injection).
Pass ofstream as a reference to your funtion or simply return string from your function and print it in main() or callee function.
In 2nd case you go like this
string f()
{
ostringstream os;
os<<"whatever I want to print in output";
....
...
return os.str();
}
int main() or //womain() from wherever you call
{
output<<f()<<endl;
}
I'm learning c++ (coming from a C and Java university coursework) and today I want to write a class that filters the bytes taken from a generic stream and writes its output to another stream.
To be coincise, let's say I want to make a class that base64-encodes the input and writes the output to stdout.
In bash I would write:
echo "some input data" | base64
In C++ i want to implement a class MyB64Encoder that would behave like this:
std::cout << myB64EncoderObject << "some input data";
//Alternatively, is it possible to make it like this?
std::cout << MyB64Encoder << "some input data";
The thing is, the myB64EncoderObject has, of course, to maintain an internal state and an internal buffer. To prevent blocking and excessive memory usage, it must be able to read and process small chunks of data and output each one of them immediately after it has been processed.
There are a few more things to take care of:
The object must wait for the output stream to be able to receive data
The object must throw an error if there is no stream reading from it (kinda like a broken pipe?)
What would be the best approach to a problem like this, in terms of efficiency? How would I implement it in modern C++1x?
The existing things that behave like this:
std::cout << myB64EncoderObject << "some input data";
are I/O manipulators (eg. std::boolalpha, std::hex, ...). However, these just set flags on the stream that it already knows how to interpret.
If you want to keep that syntax, you'll need to something more complex, namely an intermediate wrapper:
class B64Wrapper {
std::ostream &os_;
B64Encoder &enc_; // only if your encoder is really stateful
public:
B64Wrapper() = delete;
B64Wrapper(B64Wrapper&&) = default;
B64Wrapper(B64Wrapper const&) = default;
B64Wrapper(std::ostream &os, B64Encoder &enc) : os_(os), enc_(enc) {}
template <typename T>
B64Wrapper& operator<< (B64Wrapper &self, T val) {
self.enc_.encode(os_, val);
return self;
}
};
B64Wrapper operator<< (std::ostream &os, B64Encoder &enc) {
return B64Wrapper(os, enc);
}
(note you still need to write the B64Encoder::encode(std::ostream &, T value) method).
If your encoder isn't really stateful, you don't need a reference to it, and declare B64Encoder as an empty tag type with a global instance to get the same effect - in that case it only exists to select the operator<< overload.
The other approach is to write a std::basic_streambuf implementation which encodes the input to sputc/sputn/xsputn. It can forward everything else to a wrapped streambuf or to the base class, depending on what you inherit from.
You can do something like this:
class MyEncoder
{
public:
private:
std::ostream* os = nullptr;
// This overload deals with:
// std::cout << myEncoder ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder& me)
{
// grab a reference to the target output stream
me.os = &os;
return me;
}
// This overload deals with:
// std::cout << MyEncoder() ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder&& me)
{
// the temporary is currently bound to the l-value parameter me
// so we can just pass this call on to the previous overload
return os << me;
}
// This overload deals with:
// myEncoder << <anything else>
template<typename T>
friend MyEncoder& operator<<(MyEncoder& me, T const& v)
{
// only encode if there is an output stream to send the data to
// this will only be set if one of the above overloads was called
if(!me.os)
throw std::runtime_error("no stream to receive encoded data");
// do your encoding here
(*me.os) << "{encoded: " << v << "}";
return me;
}
};
Basically to achieve this:
std::cout << MyEncoder() << "some data: " << 45;
// ^ calls operator<<(MyEncoder&, 45)
// ^ calls operator<<(MyEncoder&, "some data: ")
// ^ calls operator<<(std::cout, MyEncoder())
The calls go left to right.
It may seem a little involved but it is basically covering 3 different call possibilities.
MyEncoder encoder;
std::cout << encoder; // MyEncoder& object
std::cout << MyEncoder(); // (temporary) MyEncoder&& object
encoder << "anything else" // A MyEncoder& receiving any other object
The first 2 operators are overloaded to set the internal std::ostream* and the third operator is overloaded to do the actual encoding.
I would like to be able to do:
foo(stringstream()<<"number = " << 500);
EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.
inside foo will print the string to screen or something of the sort.
now since stringstream's operator<< returns ostream&, foo's signature must be:
foo(ostream& o);
but how can I convert ostream& to string? (or char*).
Different approaches to achieving this use case are welcome as well.
The obvious solution is to use dynamic_cast in foo. But the given
code still won't work. (Your example will compile, but it won't do what
you think it should.) The expression std::ostringstream() is a
temporary, you can't initialize a non-const reference with a temporary,
and the first argument of std::operator<<( std::ostream&, char const*)
is a non-const reference. (You can call a member function on a
temporary. Like std::ostream::operator<<( void const* ). So the code
will compile, but it won't do what you expect.
You can work around this problem, using something like:
foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush() returns a non-const reference, so there are no
further problems. And on a freshly created stream, it is a no-op.
Still, I think you'll agree that it isn't the most elegant or intuitive
solution.
What I usually do in such cases is create a wrapper class, which
contains it's own std::ostringstream, and provides a templated
member operator<< which forwards to the contained
std::ostringstream. Your function foo would take a const
reference to this—or what I offen do is have the destructor call
foo directly, so that the client code doesn't even have to worry about
it; it does something like:
log() << "number = " << 500;
The function log() returns an instance of the wrapper class (but see
below), and the (final) destructor of this class calls your function
foo.
There is one slight problem with this. The return value may be copied,
and destructed immediately after the copy. Which will wreck havoc with
what I just explained; in fact, since std::ostringstream isn't
copyable, it won't even compile. The solution here is to put all of the
actual logic, including the instance of std::ostringstream and the
destructor logic calling foo in a separate implementation class, have
the public wrapper have a boost::shared_ptr to it, and forward. Or
just reimplement a bit of the shared pointer logic in your class:
class LogWrapper
{
std::ostringstream* collector;
int* useCount;
public:
LogWrapper()
: collector(new std::ostringstream)
, useCount(new int(1))
{
}
~LogWrapper()
{
-- *useCount;
if ( *useCount == 0 ) {
foo( collector->str() );
delete collector;
delete useCount;
}
}
template<typename T>
LogWrapper& operator<<( T const& value )
{
(*collector) << value;
return *this;
}
};
Note that it's easy to extend this to support optional logging; just
provide a constructor for the LogWrapper which sets collector to
NULL, and test for this in the operator<<.
EDITED:
One other thing occurs to me: you'll probably want to check whether the
destructor is being called as a result of an exception, and not call
foo in that case. Logically, I'd hope that the only exception you
might get is std::bad_alloc, but there will always be a user who
writes something like:
log() << a + b;
where the + is a user defined overload which throws.
I would suggest you to use this utility struct:
struct stringbuilder
{
std::stringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator std::string() { return ss.str(); }
};
And use it as:
void f(const std::string & s );
int main()
{
char const *const pc = "hello";
f(stringbuilder() << '{' << pc << '}' );
//this is my most favorite line
std::string s = stringbuilder() << 25 << " is greater than " << 5 ;
}
Demo (with few more example) : http://ideone.com/J995r
More on my blog : Create string on the fly just in one line
You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:
#include <iostream>
#include <sstream>
static void foo( std::string const &s )
{
std::cout << s << std::endl;
}
struct StreamProxy
{
std::stringstream stream;
operator std::string() { return stream.str(); }
};
template <typename T>
StreamProxy &operator<<( StreamProxy &s, T v )
{
s.stream << v;
return s;
}
static StreamProxy make_stream()
{
return StreamProxy();
}
int main()
{
foo( make_stream() << "number = " << 500 );
}
This program prints
number = 500
The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.
A couple of options other than the nice proxy solution just presented by Frerich Raabe:
Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.
Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.
If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro
#define build_string(expr) \
(static_cast<ostringstream*>(&(ostringstream().flush() << expr))->str())
And suppose you foo has signature void foo(const string&), you only need the one-liner
foo(build_string("number = " << 500))
This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.
Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.
Since you're converting to string anyways, why not
void foo(const std::string& s)
{
std::cout << "foo: " << s << std::endl;
}
...
std::stringstream ss;
ss << "number = " << 500;
foo(ss.str());
This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.
EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.
You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.
On top of that, you can add support for manipulators (std::hex) if needed.
I'm trying to write my own logging class and use it as a stream:
logger L;
L << "whatever" << std::endl;
This is the code I started with:
#include <iostream>
using namespace std;
class logger{
public:
template <typename T>
friend logger& operator <<(logger& log, const T& value);
};
template <typename T>
logger& operator <<(logger& log, T const & value) {
// Here I'd output the values to a file and stdout, etc.
cout << value;
return log;
}
int main(int argc, char *argv[])
{
logger L;
L << "hello" << '\n' ; // This works
L << "bye" << "alo" << endl; // This doesn't work
return 0;
}
But I was getting an error when trying to compile, saying that there was no definition for operator<< (when using std::endl):
pruebaLog.cpp:31: error: no match for ‘operator<<’ in ‘operator<< [with T = char [4]](((logger&)((logger*)operator<< [with T = char [4]](((logger&)(& L)), ((const char (&)[4])"bye")))), ((const char (&)[4])"alo")) << std::endl’
So, I've been trying to overload operator<< to accept this kind of streams, but it's driving me mad. I don't know how to do it. I've been loking at, for instance, the definition of std::endl at the ostream header file and written a function with this header:
logger& operator <<(logger& log, const basic_ostream<char,char_traits<char> >& (*s)(basic_ostream<char,char_traits<char> >&))
But no luck. I've tried the same using templates instead of directly using char, and also tried simply using "const ostream& os", and nothing.
Another thing that bugs me is that, in the error output, the first argument for operator<< changes, sometimes it's a reference to a pointer, sometimes looks like a double reference...
endl is a strange beast. It isn't a constant value. It's actually, of all things, a function. You need a special override to handle the application of endl:
logger& operator<< (logger& log, ostream& (*pf) (ostream&))
{
cout << pf;
return log;
}
This accepts insertion of a function that takes an ostream reference and returns an ostream reference. That's what endl is.
Edit: In response to FranticPedantic's interesting question of "why can't the compiler deduce this automatically?". The reason is that if you delve yet deeper, endl is actually itself a template function. It's defined as:
template <class charT, class traits>
basic_ostream<charT,traits>& endl ( basic_ostream<charT,traits>& os );
That is, it can take any sort of ostream as its input and output. So the problem isn't that the compiler can't deduce that T const & could be a function pointer, but that it can't figure out which endl you meant to pass in. The templated version of operator<< presented in the question would accept a pointer to any function as its second argument, but at the same time, the endl template represents an infinite set of potential functions, so the compiler can't do anything meaningful there.
Providing the special overload of the operator<< whose second argument matches a specific instantiation of the endl template allows the call to resolve.
endl is an IO manipulator, which is a functor that accepts a stream by reference, performs some operation on it, and returns that stream, also by reference. cout << endl is equivalent to cout << '\n' << flush, where flush is a manipulator that flushes the output buffer.
In your class, you just need to write an overload for this operator:
logger& operator<<(logger&(*function)(logger&)) {
return function(*this);
}
Where logger&(*)(logger&) is the type of a function accepting and returning a logger by reference. To write your own manipulators, just write a function that matches that signature, and have it perform some operation on the stream:
logger& newline(logger& L) {
return L << '\n';
}
I believe that the problem is your stream doesn't overload operator<< to accept a function that has the same type as std::endl as illustrated in this answer: std::endl is of unknown type when overloading operator<<
In C++ it is the stream buffer that encapsulates the underlying I/O mechanisim. The stream itself only encapsulates the conversions to string, and the I/O direction.
Thus you should be using one of the predefined stream classes, rather than making your own. If you have a new target you want your I/O to go to (like a system log), what you should be creating is your own stream buffer (derived from std::streambuf).