1

ログの重大度が異なる複数のストリームを持つロガーを作成しようとしています。

class Logger{
public:
    std::ostream& errStream;
    std::ostream& warnStream;
}

このようにして、ストリームをそのまま使用できます。

Logger L;
L.errStream << "This is an error message.";
L.warnStream << "This is a warning message.";

問題は、各ストリームの operator<< を個別にオーバーロードするにはどうすればよいかということです。つまり、どのストリームに書き込まれるかに基づいて、さまざまなアクションを実行したいということです。

それが役立つ場合は、引数として std::string を取る errWrite と warnWrite のメンバー関数が既にあります。

void errWrite(std::string);
void warnWrite(std::string);

これらを使用するには、次のようにします。

Logger L;
L.errWrite("This is an error message.");
L.warnWrite("This is a warning message.");

これらの問題は、私のコードが既に満たされている std::cout と std::cerr の代わりにドロップされないことです。既存のコードに簡単にドロップできるものを開発しようとしていました。したがって、最終的には次のいずれかが必要です。

  1. 異なるメンバーに対して個別に演算子をオーバーロードする方法。
  2. 私がやろうとしていることに対する代替アプローチ。

ありがとう。

4

3 に答える 3

2

をオーバーロードするoperator<<には、型が異なる必要があります。

したがって、これを行うには、新しいクラスを作成してstd::ostream、たとえばowarnstreamとを置き換える必要がありoerrstreamます。

私はこのようなものがうまくいくと思います:

class oerrstream
{
 private:
   std::ostream& st;

 public:
   oerrstream(std::ostream &stream) : st(stream) {}
   std::ostream& getStream() { return st; };
};

次に、次を使用してオーバーライドできます。

oerrstream& operator<<(oerrstream &es, const std::string& s)
{
   es.getStream() << s;
   return es;
}

すべての出力操作をオーバーライドする必要があることに注意してください...次のように、テンプレートを使用してそれを行うとうまくいく場合があります。

template <typename T>
oerrstream& operator<<(oerrstream &es, T t)
{
   es.getStream() << t;
   return es;
}
于 2013-08-27T10:59:42.980 に答える
0

つまり、どのストリームに書き込まれるかに基づいて、さまざまなアクションを実行したいということです。

「さまざまなアクション」が何を意味するのかはわかりませんが、解釈は次のとおりです。

class Logger{
private:
    std::ostream& errStream;
    std::ostream& warnStream;

public:

    enum { err, warn } stream_type;


    std::ostream& get(stream_type const st)
    {
        // different actions per stream:
        switch(st)
        {
        case err:
            return errStream << "Error [" << gettime_function() << "] ";
        case warn:
            return warnStream << "Warning: ";
        }
    }
};

編集:

ストリーム自体を特殊化したい場合は、テンプレート化された出力演算子を簡単に定義できます。

class ErrorStream
{
     std::ostream& underlying_;
public:
    ErrorStream(std::ostream& underlying) : underlying_(underlying) {}
    template<typename T> friend ErrorStream& operator << (
        ErrorStream& out, const T& arg)
    {
        // custom action for error stream goes here
        out.underlying_ << arg;
        return out;
    }
};

この演算子は、機能する T に対してoperator<< (std::ostream&, const T&)機能します。

于 2013-08-27T11:05:41.717 に答える