代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

如何为模板专用化创建类型标记

  •  1
  • Björn Pollex  · 技术社区  · 15 年前

    我有一个支持 iostream -通过模板 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 在他们的日志消息末尾。我的问题是,这个解决方案有什么缺陷吗,或者有一些既定的模式来做这个吗?

    提前谢谢!

    3 回复  |  直到 15 年前
        1
  •  2
  •   UncleBens    15 年前

    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 ;) 
    }
    

    只是一个可供选择的选择。

    顺便说一句,我觉得没必要 专门从事 接线员:如果不是更好的话,正常的过载也一样。

        2
  •  0
  •   jpalecek    15 年前

    我认为你的解决办法是可以接受的。如果你想用不同的方式来做,你可以创建一个类 Message ,它将代替 MyLoggingClass 并提供自动终止。

    {
      Message m;
      m << "Line: " << l; // or m << line(l) 
      m << "Message: foo"; // or m << message("foo");
      log << m; // this would automatically format the message
    }
    
        3
  •  0
  •   Community CDub    8 年前

    我已经做到了 this way 就像其他人一样。有一个功能 Error / Log / Warning /等等,看起来像这样

    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";