Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;禁用链接调用而不在指令中换行_C++_Preprocessor Directive - Fatal编程技术网

C++ C++;禁用链接调用而不在指令中换行

C++ C++;禁用链接调用而不在指令中换行,c++,preprocessor-directive,C++,Preprocessor Directive,我正在为我的项目开发一个简单的记录器包装器,它可以让我轻松地交换后端。 这是我理想的界面: log::error << "some" << " log " << "message"; 这很好,除了我需要一个干净的方式禁用日志记录。 如果我没有使用链接,我的日志函数可以使用预处理器指令删除函数的内容 void log (std::string) { #ifdef LOGGING_ENABLED // log message #endif }

我正在为我的项目开发一个简单的记录器包装器,它可以让我轻松地交换后端。
这是我理想的界面:

log::error << "some" << " log " << "message";
这很好,除了我需要一个干净的方式禁用日志记录。 如果我没有使用链接,我的日志函数可以使用预处理器指令删除函数的内容

void log (std::string) {
  #ifdef LOGGING_ENABLED
    // log message
  #endif
}
然后编译器将优化并删除空函数调用。但我不知道如何使用我正在尝试实现的api做到这一点。我知道这是可能的,因为它不知怎么做了

使用这样的指令违背了拥有一个好的api的目的

#ifdef LOGGING_ENABLED
  log << "this" << " is " << "a " << "test";
#endif
#已启用ifdef日志记录

log这不是最漂亮的,但你可以这样做:

#ifdef LOGGING_ENABLED
#define LOG(message) message
#else
#define LOG(message)
#endif


LOG(log << "this" << "is" << "a" << "test");
#已启用ifdef日志记录
#定义日志(消息)消息
#否则
#定义日志(消息)
#恩迪夫

LOG(LOG您必须插入另一个
Sink
,它在记录时不起任何作用。Glog将其称为空流:

// A class for which we define operator<<, which does nothing.
class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
 public:
  // Initialize the LogStream so the messages can be written somewhere
  // (they'll never be actually displayed). This will be needed if a
  // NullStream& is implicitly converted to LogStream&, in which case
  // the overloaded NullStream::operator<< will not be invoked.
  NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
  NullStream(const char* /*file*/, int /*line*/,
             const CheckOpString& /*result*/) :
      LogMessage::LogStream(message_buffer_, 1, 0) { }
  NullStream &stream() { return *this; }
 private:
  // A very short buffer for messages (which we discard anyway). This
  // will be needed if NullStream& converted to LogStream& (e.g. as a
  // result of a conditional expression).
  char message_buffer_[2];
};

// Do nothing. This operator is inline, allowing the message to be
// compiled away. The message will not be compiled away if we do
// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
// converted to LogStream and the message will be computed and then
// quietly discarded.
template<class T>
inline NullStream& operator<<(NullStream &str, const T &) { return str; }

<代码> //一类定义运算符

流式方法有一个问题,即使是空流:C++中没有懒惰计算。 也就是说,即使您的流对参数不做任何处理,参数仍然是完全创建的

避免此计算的唯一方法是使用宏:

#define LOG(Message_) \
    do (LogManager::activated()) {
        logger << Message_;
    } while(0);
#定义日志(消息)\
do(LogManager::activated()){

记录器非常棒,但是无法删除虚拟
接收器的复制构造函数,或者需要一个移动构造函数。
// A class for which we define operator<<, which does nothing.
class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
 public:
  // Initialize the LogStream so the messages can be written somewhere
  // (they'll never be actually displayed). This will be needed if a
  // NullStream& is implicitly converted to LogStream&, in which case
  // the overloaded NullStream::operator<< will not be invoked.
  NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
  NullStream(const char* /*file*/, int /*line*/,
             const CheckOpString& /*result*/) :
      LogMessage::LogStream(message_buffer_, 1, 0) { }
  NullStream &stream() { return *this; }
 private:
  // A very short buffer for messages (which we discard anyway). This
  // will be needed if NullStream& converted to LogStream& (e.g. as a
  // result of a conditional expression).
  char message_buffer_[2];
};

// Do nothing. This operator is inline, allowing the message to be
// compiled away. The message will not be compiled away if we do
// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
// converted to LogStream and the message will be computed and then
// quietly discarded.
template<class T>
inline NullStream& operator<<(NullStream &str, const T &) { return str; }
#ifdef LOGGING_ENABLED
  /* your sink */
#else
  struct Sink {
    Sink (std::string)  {}
    Sink (Sink const& orig) {};
  };
  template <typename T> Sink operator<<(Sink s, T) { return s; }
#endif
#define LOG(Message_) \
    do (LogManager::activated()) {
        logger << Message_;
    } while(0);