I want to get a C++ class Xyz such that the following:
Xyz mything("/tmp/x1");
int main(int argc, char **argv) {
mything << "Hello world";
}
causes a file "/tmp/x1" to be created, and the following
2013-12-04 12:01 :: Hello world
to be written to it.
The first issue I have is that ostream has many specialised methods for each type that may follow the <<. The second is that if I have
cout << "hello" << "world";
and
cout << "hello";
then the implementation for operator << called for "hello" needs to know whether anything follows it in the statement (how do I effectively do an if(last_in_line_of_<<) type construct?).
The standard cout does this by having objects like endl.
Basically I want to create a global log object with a single line, once the class has been defined, and to write to it with ostream operations such that the string that, say, cout would get would be wrapped in a larger string.
I've ended up looking at this way of doing it since the varargs way is painful and many people seem to recommend against it.
In scripting languages like Python and Ruby, objects have a str or to_s method (or equivalent) and print and format call these to format them, so that "hello {} world".format(x) formats one parameter, and "hello {} world".format(" ".join(x)) joins a list, after formatting to strings, with spaces and then sticks that into the resulting string.
I'm wondering what the right C++ way is to do this.
Instad to giving to
Xyza stream behavior, make it a manipulator and use normal streams facilities:A function prototyped as
can be used as
if std::cout is replaced by whatever other ostream (like a
outfilevariable of typestd::filestream) you get exactly that effect, but using a manipulator that can work with whatever type of output stream (non necessarily a file)