2

ストリーム演算子を使用するロギング クラスを実装しています。基本的な考え方は、カスタム型が を実装しoperator<<て、ロギングの読み取り可能な表現を提供できるというものです。ロギング クラスは、さまざまなメッセージを「収集」し、破棄時に単一のロギング エントリとして (syslog などに) 転送します。

class log_stream : public std::ostringstream
{
    inline ~log_stream()
    {
        forward_to_log(str().c_str());
    }
};

class custom_type
{
};

std::ostream &operator<<(std::ostream &stream, const custom_type &)
{
    stream << "<custom_type data>";
    return stream;
}

log_stream() << "error in custom type: " << custom_type_variable;

これは、ステートメントが std::ostream からのオーバーロードで開始されず、代わりに直接カスタム型で開始されない場合を除いて、実際には非常にうまく機能します。

log_stream() << custom_type_variable; // no known conversion from 'log_stream'
                                      // to 'basic_ostream<char, ...>&
                                      // for 1st argument

is log_stream-a ostringstreamis-a basic_ostringstreamis-a basic_ostream. 何か案は?

operator<<さらに、オーバーロードをlog_stream&直接提供する方法はありますstd::ostreamか?log_streamfstream

編集#1

「r値対応」operator<<が追加された場合、最初の問題は解決されます。

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type)
{
    return operator<<(stream, std::forward<Type>(type));
}

ただし、基本クラスへの型変換で現在/まだ壊れています(それostringstreamまたはostream)。

log_stream() << custom_type(); // OK
log_stream() << custom_type() << "text"; // OK

log_stream() << "next"; // non-const lvalue reference to type 'log_stream' cannot bind
                        // to a value of unrelated type 'basic_ostream<char, ...>'

basic_ostream<char, ...>タイプが無関係なのはなぜですか?の基本クラスでありlog_streamここでこの基本クラスへの参照を取得できるはずですよね?

編集#2

もちろん、 memberoperator<<を呼び出す必要があります。これにより、機能します。

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type)
{
    stream << std::forward<Type>(type);
    return stream;
}

したがって、問題は C++11 で解決されますが、C++03 ( argh )ではまだ機能しません。

頭に浮かぶ解決策の 1 つは、「r 値から l 値への変換演算子」を最短形式で提供することoperator()です。

class log_stream
{
    inline log_stream &()() 
    {
        return *this;
    }
}

log_stream()() << custom_type() << "text";

きれいではありませんが、何か。より良い(よりきれいな)アイデアはありますか?

4

1 に答える 1

2

ログ ストリームは一時的なものですが、挿入演算子には非 const 参照が必要です。前者を後者に変換することはできません。

タイプの実際の名前付き変数を導入し、log_streamそれを の左オペランドとして使用する必要があり<<ます。

于 2013-04-21T13:37:26.517 に答える