The only way to achieve the log<i> << ...
syntax is to make log
a variable template. Note that this will break log << ...
and log.Foo()
syntax.
#include <iostream>#include <string>class Logger{ int loglevel = 0; public: Logger(int loglevel) : loglevel(loglevel) {} Logger& operator<<(const std::string &s) { std::cerr << loglevel << "->" << s << '\n'; return *this; }};template <int N> Logger log(N);int main(){ log<2> << "blah";}
This would give you N "loggers", one per log level, so they should probably hold pointers to the one single underlying logger.
I don't think this is a good idea overall. Firstly, too much effort for a tiny bit of syntax sugar. And second, in the modern day you should probably design your logger around std::format
, which means all your logging statements become function calls, such as:
log(i, "format", args...);log<i>("format", args...);
And this call syntax is trivial to implement.