c++ log functions using template SFINAE for conditional compile -


i evaluating if possible leverage c++11 features replace logging macros without run-time additional cost.

i come out demo:

enum class loglevel {     fatal = 0,     dfatal = 1,     error = 2,     normal = 3,     verbose = 4,     debug = 5 };  constexpr loglevel log_compiled = loglevel::normal; loglevel log_runtime = loglevel::error;  #ifdef ndebug constexpr loglevel log_fatal = loglevel::fatal; #else constexpr loglevel log_fatal = loglevel::dfatal; #endif   template <loglevel l, typename std::enable_if<(l <= log_fatal)>::type* = nullptr> void log(std::string message) {      std::cout << "fatal level: " << (int) l << " message: " << message << std::endl;     exit(0); }  template <loglevel l, typename std::enable_if<(l>log_fatal && l <= log_compiled)>::type* = nullptr> void log(std::string message) {      if (l <= log_runtime) {         std::cout << "level: " << (int) l << " message: " << message << std::endl;     }  }  template <loglevel l, typename std::enable_if<(l > log_compiled)>::type* = nullptr> void log(std::string message) { }  int main(int argc, char *argv[]) {      //not compiled     log<loglevel::verbose>("something usual");      //compiled, not printed     log<loglevel::normal>("something usual");      //compiled, printed     log<loglevel::error>("no disk space");      //compiled, printed, terminate in debug mode     log<loglevel::dfatal>("unexpected contition, recoverable");      //compiled, printed, terminate     log<loglevel::fatal>("unexpected contition, unrecoverable");      return 0; } 

this way handle compile time exclusion, runtime log level , fatal conditions in consistent way.

it adapted streams << operator.

my questions:

//not compiled log<loglevel::verbose>("something usual"); 

will result in noop compilers? string exist in code?

is approach bad idea?

as written, compiler cannot optimize away

log<loglevel::verbose>("something usual"); 

because constructs , destructs std::string, may have side effects (e.g., allocating , freeing memory using possibly-replaced ::operator new , ::operator delete).

if write log templates take const char * instead, however, call can optimized out. given

template <loglevel l, typename std::enable_if<(l > log_compiled)>::type* = nullptr> void log(const char * ) { }  int main() {     log<loglevel::verbose>("something usual");     return 0; } 

g++ 4.9 @ -o2 compiles it simply

xorl    %eax, %eax ret 

Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -