A typical LOG() macro-based logging solution may look something like this:
#define LOG(msg) \\
std::cout << __FILE__ << \"(\" << __LINE__ &
Here is another expression template which seems to be even more efficient based on some tests that I've run. In particular, it avoids creating multiple functions for strings with different lengths by specializing operator<<
to use a char *
member in the resulting structure. It should also be easy to add other specializations of this form.
struct None { };
template
struct Pair {
First first;
Second second;
};
template
struct LogData {
List list;
};
template
LogData>
operator<<(LogData begin,const Value &value)
{
return {{begin.list,value}};
}
template
LogData>
operator<<(LogData begin,const char (&value)[n])
{
return {{begin.list,value}};
}
inline void printList(std::ostream &os,None)
{
}
template
void printList(std::ostream &os,const Pair &data)
{
printList(os,data.first);
os << data.second;
}
template
void log(const char *file,int line,const LogData &data)
{
std::cout << file << " (" << line << "): ";
printList(std::cout,data.list);
std::cout << "\n";
}
#define LOG(x) (log(__FILE__,__LINE__,LogData() << x))
With G++ 4.7.2, with -O2 optimization, this creates a very compact instruction sequence, equivalent to filling a struct with the parameters using a char *
for string literals.