A better LOG() macro using template metaprogramming

后端 未结 2 1048
臣服心动
臣服心动 2021-01-30 03:16

A typical LOG() macro-based logging solution may look something like this:

#define LOG(msg) \\
    std::cout << __FILE__ << \"(\" << __LINE__ &         


        
2条回答
  •  再見小時候
    2021-01-30 03:45

    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.

提交回复
热议问题