I'm trying to implement my own qDebug() style debug-output stream, this is basically what I have so far:
struct debug
{
#if defined(DEBUG)
template<typename T>
std::ostream& operator<<(T const& a) const
{
std::cout << a;
return std::cout;
}
#else
template<typename T>
debug const& operator<<(T const&) const
{
return *this;
}
/* must handle manipulators (endl) separately:
* manipulators are functions that take a stream& as argument and return a
* stream&
*/
debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
{
// do nothing with the manipulator
return *this;
}
#endif
};
Typical usage:
debug() << "stuff" << "more stuff" << std::endl;
But I'd like not to have to add std::endl;
My question is basically, how can I tell when the return type of operator<< isn't going to be used by another operator<< (and so append endl)?
The only way I can think of to achieve anything like this would be to create a list of things to print with associated with each temporary object created by qDebug(), then to print everything, along with trailing newline (and I could do clever things like inserting spaces) in ~debug(), but obviously this is not ideal since I don't have a guarantee that the temporary object is going to be destroyed until the end of the scope (or do I?).
Something like this will do:
struct debug {
debug() {
}
~debug() {
std::cerr << m_SS.str() << std::endl;
}
public:
// accepts just about anything
template<class T>
debug &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
std::ostringstream m_SS;
};
Which should let you do things like this:
debug() << "hello world";
I've used a pattern like this combined with a lock to provide a stream like logging system which can guarantee that log entries are written atomically.
NOTE: untested code, but should work :-)
Qt uses a method similar to #Evan. See a version of qdebug.h for the implementation details, but they stream everything to an underlying text stream, and then flush the stream and an end-line on destruction of the temporary QDebug object returned by qDebug().
When you write that this is the typical usage:
debug() << "stuff" << "more stuff" << std::endl;
are you definitely planning to construct a debug object each time you use it? If so, you should be able to get the behavior you want by having the debug destructor add the newline:
~debug()
{
*this << std::endl;
... the rest of your destructor ...
}
That does mean you cannot do something like this:
// this won't output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
The stream insertion (<<) and extraction (>>) are supposed to be non-members.
My question is basically, how can I
tell when the return type of
operator<< isn't going to be used by
another operator<< (and so append
endl)?
You cannot. Create a member function to specially append this or append an endl once those chained calls are done with. Document your class well so that the clients know how to use it. That's your best bet.
Related
I have been trying to rework my logging class. However, I'm facing a problem.
I want to expose this interface to users:
mylog() << "hello";
The idea is that mylog is an instance of Logger, which defines some useful characteristics for a defined log type. Its operator() function would return an instace of type LogStream. However, I would like to output the newline character automatically at the end, so I had the idea to do that in LogStream's destructor.
My current implementation looks like this (LogStream and Logger being largely dumbed down):
#include <iostream>
struct LogStream
{
~LogStream() { std::cout << '\n'; }
template<class T>
LogStream& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
struct Logger
{
LogStream operator()()
{
return LogStream{} << "message: ";
}
};
int main()
{
Logger log;
log() << "hello!";
}
Interstingly, I figured out with this piece of code that my previous implementation depended on RVO. The compiler was always performing copy-elision, so the destructor did behave the way I want. However, with this piece of code, the newline character is being printed twice, because the copy constructor is being called when the copy occurs in operator().
The problem disappears when I do not return the temporary instance, and instead put this in operator()'s body:
LogStream stream;
stream << "message: ";
return stream;
Now the RVO makes it work the way I want.
I later on = delete'd the copy constructors, because it made more sense anyway, which effectively causes the code to fail to compile.
What are my options to provide the interface I want, without using the hacky solution to rely on RVO?
Add a constructor to LogStream that takes a char const *.
LogStream(char const* c) { std::cout << c; }
Then, instead of creating a temporary LogStream within operator(), use list-initialization to initialize the return value itself.
LogStream operator()()
{
return {"message: "};
}
The temporary is thus avoided along with the extra new line.
Live demo (note that even using -fno-elide-constructors to disable copy elision doesn't result in the extra newline).
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 am wondering what's the best practice to print out a class (say classA), I have several method
classA ca;
1) Define a debug method and inside this method , print out all its members.
2) Define a str() method, and use cout<< ca.str()
3) Define something like string conversion(I am not sure how yet), and just use cout << ca
The usual way is to overload operator<< roughly like this:
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case. Do the same thing you would
// if you wanted to print a to cout or a file, because that is what this code
// will end up doing.
out << a.some_data() << ", " << a.some_more_data();
return out;
}
If classA has a limited interface (does not expose all relevant data members), it may be necessary to make the operator<< a friend of classA, such as
class A {
public:
// stuff
friend operator<<(std::ostream &out, classA const &a);
};
// private members can then be accessed
std::ostream &operator<<(std::ostream &out, classA const &a) {
out << a.some_private_member << ", " << a.some_other_private_member;
return out;
}
There is not usually a good reason to prevent read access to private members that you then enable the user to dump out per operator<<, though, since it would be rather leaky access control.
This then enables you to write
classA a;
std::cout << a;
std::ofstream file("foo.txt");
file << a;
std::ostringstream fmt;
fmt << a;
std::string s = fmt.str();
and so forth.
As a style note: It is possible to write
std::ostream &operator<<(std::ostream &out, classA const &a) {
// precise formatting depends on your use case
return out << a.some_data() << ", " << a.some_more_data();
}
This achieves the same thing as the split return because operator<< (by convention) returns the same stream object that was passed into it (to enable the chaining of << as in std::cout << i << j << k;).
Style note 2: If there is nothing in classA that makes it difficult, an upgrade to this technique is to write
template<typename char_type>
std::basic_ostream<char_type> &operator<<(std::basic_ostream<char_type> &out, classA const &a) {
// rest as before. Put it in a header because it is a function template now.
}
This enables you to write classA objects not only to cout, cerr, clog, ofstream, ostringstream etc., but also to their wchar_t counterparts wcout, wcerr, wclog, wofstream, and wostringstream. These are rarely used in practice, but often it will cost you nothing to implement this feature. The trick is that std::ostream and std::wostream -- base classes of all these output streams -- are aliases for std::basic_ostream<char> and std::basic_ostream<wchar_t>, respectively. That gives us this nice way to handle both (and potentially other) character classes without code duplication.
clog can be an option if you want to log your steps of a process in some file and review the file later to see what goes wrong. Also you can check state of data members at certain interval by logging them externally in file.
I have implemented a custom logger where I dump information to the corresponding file:
like this:
Logger::log["log_file"] << "Hi" << "Hi again" << "\n";
The implementation of the operator << is as below. Kindly note the place where the buffer is dumped into the stream when it reaches a limit:
//This is the function signature of std::endl and some other manipulators
typedef CoutType& (*StandardEndLine)(CoutType&);
/// This method defines an operator<< to take in std::endl
BasicLogger& operator<<(StandardEndLine manip);
/// write the log items to buffer
template <typename T>
BasicLogger & operator<< (const T& val)
{
std::stringstream *out = BasicLogger::getOut();
*out << val;
if(out->tellp() > 512000/*500KB*/){
flushLog();
}
return *this;
}
My problem is in the lines that have multiple <<s :
Logger::log["log_file"] << "Hi" << "Hi again" << "\n";
after executing << "Hi", the buffer can get full and flushing to the stream is performed.
This is not desirable for me . I am looking for a solution to ignore that limit(500KB) if a line has not ended yet.
Example scenario:
This problem is highlighted when the application writes buffers filled by different threads to the same file: the last line of the first buffer is half written, when the second buffer from another thread writes another 500kb to the file before I can complete the last line of the first buffer.
I appreciate your thoughts and solutions.
thanks
The traditional solution to grouping multiple << into a single flush is to use a temporary sentry object which is destroyed at the end of the statement.
The destructor would flush (if required), and you can even have it append a newline automatically if that's what you want. As per Andrew Medico's comment, the sentry ctor/dtor should lock/unlock as well, if you need synchronization.
An alternative is to gather everything into a local ostringstream in the sentry, and then you only have to lock/write/flush/unlock a single string from the dtor.
Details:
your Logger::log["log_file"] operator should return a temporary object with the behaviour you chose from the options above
your various << are operator calls taking as the first argument, and returning, a reference to your sentry type
at the ;, the temporary sentry goes out of scope and does any flushing work in its destructor.
Note that if you're just delegating to an existing ostream, you can easily have a single templated Logger::sentry& operator<< (Logger::sentry&, T).
Edit: I thought I'd done this before: the question isn't a duplicate, but the answer is. https://stackoverflow.com/a/19520409/212858
I am looking for a solution to ignore that limit(500KB) if a line has not ended yet.
Why not just check that the last character is a '\n' before flushing the log?
If I knew what was in T, I would give you an example. If its a c++11 string you can just do:
char ch = val.getString().back();
if(out->tellp() > 512000/*500KB*/ && ch == '\n'){
flushLog();
}
Simply flag a carrage return:
bool ended = out.str().find('\n') != string::npos;
if(out->tellp() > 512000/*500KB*/ && ended) {
You can change the implementation of the flushLog method. I assume your implementation writes the contents of the internal stringstream into a file and clears it. You can output the contents of the stringstream only up to the last newline:
void Whatever::flushLog()
{
std::stringstream& out = *BasicLogger::getOut();
std::string stuff = out.str();
size_t pos_of_newline = stuff.rfind('\n');
if (pos_of_newline != std::string::npos)
{
std::string write_it_to_file = stuff.substr(0, pos_of_newline + 1);
... write it to file
std::string leftover = stuff.substr(pos_of_newline + 1);
out.str(leftover);
}
}
The code is only an idea; I didn't check it - maybe there are some bugs. In additon: the str() call duplicates the contents of the stringstream; you might want to use its rdbuf instead (I have no experience with rdbuf, so cannot recommend anything).
Following Useless's suggestion (A suggestion shot by a user called Useless!!!),
I solved my issue using Sentry(temporary) objects:
Logger::log["log_file"] will return the correct instance of BasicLogger
operator<< in BasicLogger will return a copy of a Sentry object.
The subsequent <<s will be taken care of by operator<< in the Sentry object
Sentry will eventually goes out of scope upon hitting ; where its destructor will do the main job:
class BasicLogger {
/// operator overload. write the log items to buffer
template<typename T>
Sentry operator<<(const T& val) {
Sentry t(*this,*getOut());
t << val;//do the first << here
return t;
}
//...
class Sentry {
std::stringstream &out;
BasicLogger &basicLogger;
public:
Sentry(BasicLogger & basicLogger_, std::stringstream &out_) :
out(out_), basicLogger(basicLogger_) {
}
Sentry(const Sentry& t) :
basicLogger(t.basicLogger), out(t.out) {
}
template<typename T>
/// operator overload
Sentry & operator<<(const T& val) {
out << val;
return *this;
}
~Sentry() {
// by some googling this estimated hardcode value promises less cycles to write to a file
if (out.tellp() > 512000/*500KB*/) {
basicLogger.flushLog();
}
}
};
//...
};
class Logger {
//...
public:
static Logger log;
virtual BasicLogger & operator[](const std::string &key);
virtual ~Logger();
};
I am trying to overload the stream operator as a diagnostic tool for various objects in my code. Ideally I would like to be able to modify the stream on the fly with those stream modifier flags, however these are very limited and I don't really want to sprinkle setVerbose flags in each of my objects. I ended up with the following rather poor but working solution
#include <iostream>
#include <string>
#include <vector>
struct StructA {
std::string mLongName;
std::string mShortName;
inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) {
// I dont know how to use a generic verbose flag - so use this - very bad idea
// but perhaps the stackoverflow people can help out with a good suggestion
if (os.flags() & os.skipws) {
os << rStruct.mShortName << std::endl;
} else {
os << rStruct.mLongName << std::endl;
}
return os;
}
};
int main()
{
StructA test {"Verbose Name", "Short Name"};
std::cout << test << std::noskipws << test << test << std::skipws << test;
}
I created the above live example to demonstrate my point, and it prints the following output:
Short Name
Verbose Name
Verbose Name
Short Name
As you can see, I am using a totally inappropriate 'skipws' stream modifier flag as a poor man's 1 level verbose flag - that was just to show the in stream approach I was looking for without havnig to add a member object to each of my printable objects (all suggestions for better approaches would be welcome but I would like to minimize the changes to each of my printable objects - as I have quite a lot). Secondly the flag is persistent until reset later - some other stream flags only last for the next stream operator but I am not exactly sure how that works and thirdly
You can store custom state in your stream instance:
See it Live On Coliru
#include <iostream>
static int const index = std::ios_base::xalloc();
std::ostream& verbose(std::ostream& stream) {
stream.iword(index) = 1;
return stream;
}
std::ostream& noverbose(std::ostream& stream) {
stream.iword(index) = 0;
return stream;
}
struct StructA {
std::string mLongName;
std::string mShortName;
inline friend std::ostream& operator << (std::ostream& os, const StructA& rStruct) {
switch (os.iword(index)) {
case 1: return os << rStruct.mLongName;
case 0:
default: return os << rStruct.mShortName;
}
}
};
int main()
{
StructA a;
a.mLongName = "loooooooooooooooooooong names are tedious";
a.mShortName = "succinctness";
std::cout << a << '\n';
std::cout << verbose;
std::cout << a << '\n';
std::cout << noverbose;
std::cout << a << '\n';
}
Credits go to Dietmar Kühl's answer.
If you needed siginificant amounts of state/logic, you would have to look at imbue-ing a custom locale facet. His answer shows the basics of this approach too.
It seems you are in this case too reluctant to create an abstraction for some reason. Don't take this personally I only write this because I once was too hesitant to do that, but create abstractions. Create a Logger class based on iostream either by inheritance or containment which behavior you can modify. Let's say the logger has options like
enum {SHORT,VERBOSE,DEBUG};
Let this option be static so that it has application wide effect on all the instances. Really there only needs to be one instance perhaps?
I realize that all your printable objects need to support the various printing options in a consistent way, i.e. all need to have shortName and longName.