1

iostream我有一个通过模板支持 -syntax的自定义日志记录类operator <<

template< class T >
MyLoggingClass & operator <<(MyLoggingClass &, const T &) {
    // do stuff
}

我也有这个操作符的专门版本,应该在日志消息完成时调用:

template< >
MyLoggingClass & operator <<(MyLoggingClass &, consts EndOfMessageType &){
    // build the message and process it
}

EndOfMessageType定义如下:

class EndOfMessageType {};
const EndOfMessageType eom = EndOfMessageType( );

定义了全局常量eom,以便用户可以像std::endl在日志消息末尾一样使用它。我的问题是,这个解决方案是否有任何陷阱,或者是否有一些既定的模式可以做到这一点?

提前致谢!

4

3 回答 3

2

std::endl是一个函数,而不是一个对象,并且operator<<被重载以接受指向函数的指针并返回对 . 的引用ostream。这个重载只是调用函数并传递*this.

#include <iostream>

int main()
{
    std::cout << "Let's end this line now";
    std::endl(std::cout); //this is the result of cout << endl, or cout << &endl ;) 
}

只是一个可供考虑的替代方案。

顺便说一句,我认为没有必要专门化运算符:正常的重载也一样好,如果不是更好的话。

于 2010-08-25T15:56:20.323 回答
0

我已经这样做了就像其他人一样。有一个函数///Error等看起来像这样LogWarning

DiagnosticBuilder Error( ErrType type, string msg, int line );

这将返回一个临时构建器对象,其类基本上定义为

struct DiagnosticBuilder {
  DiagnosticBuilder(std::string const& format)
    :m_emit(true), m_format(format) 
  { }
  DiagnosticBuilder(DiagnosticBuilder const& other) 
    :m_emit(other.m_emit), m_format(other.m_format), m_args(other.m_args) {
    other.m_emit = false;
  }
  ~DiagnosticBuilder() {
    if(m_emit) {
      /* iterate over m_format, and print the next arg 
         everytime you hit '%' */
    }
  }

  DiagnosticBuilder &operator<<(string const& s) {
    m_args.push_back(s);
    return *this;
  }
  DiagnosticBuilder &operator<<(int n) {
    std::ostringstream oss; oss << n;
    m_args.push_back(oss.str());
    return *this;
  }
  // ...
private:
  mutable bool m_emit;
  std::string m_format;
  std::vector<std::string> m_args;
};

因此,如果您要在循环中构建日志消息,那就这样吧

DiagnosticBuilder b(Error("The data is: %"));
/* do some loop */
b << result;

一旦自动调用构建器的析构函数,就会发出消息。大多数情况下你会匿名使用它

Error("Hello %, my name is %") << "dear" << "litb";
于 2010-08-25T21:08:09.353 回答
0

我认为您的解决方案是可以接受的。如果您想以不同的方式进行操作,您可以创建一个 class Message,用于代替 yourMyLoggingClass和提供的自动终止。

{
  Message m;
  m << "Line: " << l; // or m << line(l) 
  m << "Message: foo"; // or m << message("foo");
  log << m; // this would automatically format the message
}
于 2010-08-25T14:20:43.283 回答