c++ translate ostream operator to function call - c++

I feel there should be a single liner with boost::phoenix that would let me stream an object having a member function ...::stream_to(std::ostream&) with << syntax. Something like this:
struct x { void stream_to(std::ostream&); }
LOG_INFO << MAGIC_SOMETHING(x);
But struggling to find that MAGIC_SOMETHING(...). Am specifically interested in a solution that won't require me doing a forwarding marker struct and ostream operator for it.

Related

Using my own String class with the << operator

I am looking for a way to use an ostream with my custom string class and overload the operator << to stream to the buffer which i can then flush to anywhere i want (in my case its just gonna be printed in a window)
I'm reasonably new to the inner workings of iostream's but from my understanding the method i've seen of making std::stringbuf a base of my custom stringstream would not work because the stringbuf deals with the std::string.
in essence i want to able to do this (or similar):
MyStringClass string
MyOutput << "hello" << string << "World" << std::endl;
Where MyOutput can be changed to print to anywhere i want.
Thank you.
Not a problem. Define your class, and within it's definition add an ostream& operator<<(const String&);.
Inside that operator, you can code whatever handling you want (look at std::string for inspiration)

stream operators where lhs is not a std::iostream instance

I have a custom output class that has two std::ostream members that serve different purposes. Either stream is used depending upon how the output class is configured. In some instances, the two streams are chained together. A grossly simplified version of the class is below. I can provide some more details if needed.
class c_Output
{
public:
c_Output (bool x_useA) : m_useA(x_useA) { /* setup m_stream[AB] here */ };
~c_Output ();
inline std::ostream& stream () { return (m_useA ? m_streamA : m_streamB); };
private:
bool m_useA;
std::ostream m_streamA;
std::ostream m_streamB;
}
I know how to write stream operators for classes that I wish to stream to/from std::cout, std::cin, or any other std::iostream, but I am struggling to write stream operators where a c_Output instance serves as the lhs instead of a std::ostream instance.
Right now, I am able to get away with:
c_Output l_output;
uint64_t l_value = 0xc001c0de;
l_output.stream() << std::hex << std::setw(16) << std::setfill('0') << l_value;
c_Output::stream() returns the appropriate std::ostream&, so this behaves just as expected.
I would like to rewrite the above as:
c_Output l_output;
uint64_t l_value = 0xc001c0de;
l_output << std::hex << std::setw(16) << std::setfill('0') << l_value;
I have attempted several different versions of defining operator<< based on examples I have seen here on StackOverflow and the greater web to no avail. The latest version looks like this:
// in header
class c_Output
{
...
friend c_Output& operator<< (c_Output& x_output, std::ostream& x_stream);
...
}
// in source
c_Output&
operator<< (c_Output& x_output, std::ostream& x_stream)
{
x_output.stream() << x_stream;
return x_output;
}
The setup of the arguments is intended to mirror the standard stream operator overload. This setup gives me compile issues such as:
error: no match for 'operator<<' in 'l_output << std::hex'
note: candidates are: c_Output& operator<<(c_Output&, std::ostream&)
I have stripped away all the file and line information, but it gets the point across. I am obviously getting the type for the rhs of the operator incorrect. What is the correct type and/or correct means of implementing the stream operator as desired?
There is also a complementary c_Input class that has a similar requirement, but adapting the answer for c_Output should be trivial.
The type of std::hex is std::ios_base& (*)(std::ios_base&). Change your operator signature to:
c_Output& operator<< (c_Output& x_output, std::ios_base& (*x_stream)(std::ios_base&));
operator<< (c_Output& x_output, std::ostream& x_stream)
The only real problem is that std::hex isn't a std::ostream, and with your methods no overloaded << is available for it.
In order to support the usage of the hex modifier, you'll need another friend overload with parameters (c_Output&, ios_base& (*)(ios_base&)) (as hex is a pointer to function taking reference to ios_base returning reference to ios_base).
At the rate you're going, you'll need to also implement all the other << overloads as well. This is not a trivial task, but is necessary to masquerade as a std::ostream, with or without inheriting from it.

Customized "ofstream" output

I have to extend the ofstream class to write a logging stream service.
The goal is to intercept each line, adding at the head of each one a customized text (date/time, severity, and so on).
Now, it's clear that I'm not a C++ guru, so I read a lot of documentation about this task, e.g.
http://www.angelikalanger.com/Articles/Topics.html#CPP
http://asmodehn.wordpress.com/2010/06/20/busy-c-coding-and-testing
http://gabisoft.free.fr/articles-en.html
The above articles suggest to write a custom stream buffer, but during porting of this concept on file streams I encountered a lot of difficulties.
Is there a simpler method to achieve this goal?
You don't need to write a custom stream buffer; the simplest and most straightforward way is to make a class you can send output to by giving it a templatized single argument operator<<():
template <typename T>
std::ostream& operator<<(const T& data_)
{
m_outstream << m_severity << "\t" << getTimeStamp() << "\t" << data_;
return m_outstream;
}
Where m_outstream is some type of std::ostream (std::ofstream, etc). m_severity and getTimeStamp() are examples of what you can insert (and you can create a bog standard two argument operator<<() to format and output the severity type to an ostream).
This then allows you to do things like:
myLogger << "failingFunction(" << argument <<
"): Could not do something." << std::endl;
and you will get output on m_outstream that looks like:
WARNING 2012-01-03 19:32 failingFunction("argument value"): Could not do something.
Beyond this, you will want a way to set the severity, which can be as simple as a method called on the logger class you added the templatized operator<<() to. If you want to get really fancy, you can write your own manipulator that acts much like setw() would on a std::ostream. See http://www.math.hkbu.edu.hk/parallel/pgi/doc/pgC++_lib/stdlibug/man_6665.htm for a primer on writing manipulators.

C++ stream second insertion operator

Is it possible to define a second insertion operator to have two modes of outputting a class? Say e.g. one that outputs all members and one that just outputs some basic unique identifier that is grep-able in a log? If so, is there an operator that is usually chosen? I would guess as analogy to << one might use <<< if that is legal?
Thanks
If you want to output only the id, then the best idea is probably to provide a method to get the id in a type that's streamable (e.g. std::string id() const;). That's much more intuitive to other people working on the code than some strange operator use.
Your suggestion of <<< (it's not possible to create new operators in C++, but ignoring that for a moment) reveals that you're happy for there to be different code at the point of call. Therefore, the only benefit you'd get would be the saving of a few character's source code; it isn't worth the obfuscation.
By way of contrast, there are situations where you want the same streaming notation to invoke different behaviours, such as switching between id-only and full data, or different representations such as tag/value, CSV, XML, and binary. These alternatives are usually best communicated by either:
using different stream types (e.g. XMLStream rather than std::ostream), and defining XMLStream& operator<<(XMLStream&, const My_Type&) etc, and/or
using stream manipulators - you can create your own - random Google result: http://www.informit.com/articles/article.aspx?p=171014&seqNum=2
There's no such thing already defined or in use by convention.
Also, you cannot define your own operators in C++, you have to use one of the ones already in the language and overloadable, and <<< isn't an operator in C++, so it is out anyway.
I'd strongly recommend you don't use some other operator for this. (See rule #1 here for a more thorough explanation.) If you have subtle differences between output operations, well-chosen functions names go a long way for making better code than unclear operators arbitrarily picked.
No. You can't define your own operators (<<< doesn't exist in C++). But you can define a id() method returning a string and output this.
There is no such operator as <<< in C++.
You are, however, free to implement, for example operator <(ostream&,Object&), which would do what you want. The problem is, code may get unreadable when you try to chain < and << together.
you can use operator | for instance. Another way of doing this is to define small tag classes for which the operator is overloaded; example (pretty simplistic but you get the point):
template< class T >
struct GrepTag
{
GrepTag( const T& );
T value;
}
template< class T >
Greptag< T > MakeGrepTag( const T& x )
{
return GrepTag< T >( x );
}
template< class T >
MyClass& MyClass::operator << ( const GrepTag< T >& g )
{
//output g.value here
}
MyClass() << MakeGrepTag( "text" );
Yet another way, more like the standard streams, is to use a tag as well but keep some state internally:
struct GrepTag
{
}
MyClass& MyClass::operator << ( const GrepTag& g )
{
grepState = true;
}
template< class T >
MyClass& MyClass::operator << ( const T& )
{
if( grepState )
{
//output special
grepState = false;
}
else
{
//output normal
}
}
MyClass() << GrepTag() << "text";
You cannot define your own operators in C++. You can only overload those that exist.
So I recomend not using an operator for outputting basic unique identifier grep-able in a log. This doesn't correspond to any existing operator role. Use a method instead, such as exportToLog().

Lazy evaluation with ostream C++ operators

I am looking for a portable way to implement lazy evaluation in C++ for logging class.
Let's say that I have a simple logging function like
void syslog(int priority, const char *format, ...);
then in syslog() function we can do:
if (priority < current_priority)
return;
so we never actually call the formatting function (sprintf).
On the other hand, if we use logging stream like
log << LOG_NOTICE << "test " << 123;
all the formating is always executed, which may take a lot of time.
Is there any possibility to actually use all the goodies of ostream (like custom << operator for classes, type safety, elegant syntax...) in a way that the formating is executed AFTER the logging level is checked ?
This looks like something that could be handled with expression templates. Beware, however, that expression templates can be decidedly non-trivial to implement.
The general idea of how they work is that the operators just build up a temporary object, and you pass that temporary object to your logging object. The logging object would look at the logging level and decide whether to carry out the actions embodied in the temporary object, or just discard it.
What I've done in our apps is to return a boost::iostreams::null_stream in the case where the logging level filters that statement. That works reasonably well, but will still call all << operators.
If the log level is set at compile time, you could switch to an object with a null << operator.
Otherwise, it's expression templates as Jerry said.
The easiest and most straight-forward way is to simply move the check outside of the formatting:
MyLogger log; // Probably a global variable or similar.
if (log.notice())
log << "notified!\n" << some_function("which takes forever to compute"
" and which it is impossible to elide if the check is inside log's"
" op<< or similar");
if (log.warn()) {
log << "warned!\n";
T x;
longer_code_computing(value_for, x); // easily separate out this logic
log << x;
}
If you really wanted to shorten the common case, you could use a macro:
#define LOG_NOTICE(logger) if (logger.notice()) logger <<
LOG_NOTICE(log) << "foo\n";
// instead of:
if (log.notice()) log << "foo\n";
But the savings is marginal.
One possible MyLogger:
struct MyLogger {
int priority_threshold;
bool notice() const { return notice_priority < current_priority; }
bool warn() const { return warn_priority < current_priority; }
bool etc() const { return etc_priority < current_priority; }
template<class T>
MyLogger& operator<<(T const &x) {
do_something_with(x);
return *this;
}
};
The problem here is mixing iostream-style operator overloading with a printf-like logging function – specifically translating manipulators and formatting flags/fields from iostreams into a format string. You could write to a stringstream and then chunk that to your syslog function, or try something fancier. The above MyLogger works easiest if it also contains an ostream reference to which it can forward, but you'll need a few more op<< overloads for iomanips (e.g. endl) if you do that.
For mine I made a debug_ostream class which has templated << operators. These operators check the debug level before calling the real operator.
You will need to define non-template overrides for const char* and std::ostream& (*x)(std::ostream&) because otherwise those don't work. I'm not sure why.
With inlining and high enough optimization levels the compiler will turn the whole output line into a single check of the debug level instead of one per output item.
I should add to this that this doesn't solve the original problem. For example if part of the debug line is to call an expensive function to get a value for output, that function will still be called. My solution only skips the formatting overhead.