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

あなたの解決策は受け入れられると思います。別の方法で実行したい場合は、提供された自動終了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
}
于 2010-08-25T14:20:43.283 に答える