5

私は次のクラスを持っています:

namespace {
class MimeLogger : public std::ostringstream
{
public:
    MimeLogger()
    {}

    ~MimeLogger()
    {
        LOGEVENT( logModuleWSE, logEventDebug, logMsgWSETrace1, str() );
    }
};
}

私がこれを行うとき:

MimeLogger() << "Hello " << "World";

最初の"Hello "文字列は として扱われますvoid*。コードをデバッグすると、文字列ではなくポインター値として"Hello "渡されて出力されます。std::basic_ostream::operator<< (void const*)2 番目の文字列"World"は、グローバルなオーバーロードされた << 演算子に適切に渡されますchar const*

<< 演算子の両方の使用法が同じオーバーロードに解決されることを期待していますが、これは起こりません。誰かが説明して、おそらく修正を提案できますか?

前もって感謝します。

アップデート

私は C++03 に行き詰まっていることを言い忘れましたが、一部の人が C++03 と C++11 の両方のケースをカバーしてくれたことをうれしく思います。

4

2 に答える 2

7

C++03: 式 のMimeLogger() << "Hello "場合、テンプレート関数

template <typename charT, class traits>
std::basic_ostream<charT, traits>& std::operator<< (
    std::basic_ostream<charT, traits>& os,
    const char* cstr);

一時MimeLogger()は非 const 参照にバインドされない可能性があるため、オーバーロードの解決中には考慮されません。メンバー関数のオーバーロードにはこの問題はありません。これは、暗黙的なパラメーターの規則により、一時的なパラメーターへのバインドが許可されているためです。

C++11 右辺値参照をサポートするコンパイラを使用できる場合、これは意図したとおりに動作するはずです。これは、C++11 ライブラリが追加のオーバーロードを提供するためです。

template <typename charT, class traits, typename T>
std::basic_ostream<charT, traits>& std::operator<< (
    std::basic_ostream<charT, traits>&& os,
    const T& x ); // { os << x; return os; }

これにより、一時的なストリームが一時的<<ではないかのように使用できます。

(g++ でテスト プログラムを試してみたところ、-std=c++0x を使用しない場合と使用した場合で異なる結果が得られました。)

C++11 に適したコンパイラを使用できない場合は、これを の public セクションに追加するclass MimeLoggerと、C++03 で必要なことができる回避策になります。

template<typename T>
MimeLogger& operator<<(const T& x)
{
    static_cast<std::ostringstream&>(*this) << x;
    return *this;
}

using std::ostringstream::operator<<;

using 宣言により、標準ライブラリのメンバー オーバーロードが からも確実に見えるようになりMimeLoggerます。特に、これがないとマニピュレーターstd::endlはテンプレート演算子を使用できません。これは、std::endlそれ自体が関数テンプレートであり、C++ から期待するにはあまりにも多くのテンプレート型推論であるためです。しかし、関数マニピュレーターを機能させるメンバーを非表示にしないことが確実である限り、問題はありませんostream(27.7.3.6.3):

namespace std {
    template <typename charT, class traits>
    class basic_ostream : /*...*/ {
    public:
        basic_ostream<charT, traits>& operator<<(
            basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
    };
}
于 2012-05-16T01:07:29.233 に答える
0

封じ込めを使用してみstd::ostringstream ませんか?

class MimeLogger
{
private:
    std::ostringstream oss_m;

public:
    MimeLogger()
    {
    }

    ~MimeLogger()
    {
        std::cout << __FILE__ << "(" << __LINE__ << "):" << oss_m.str() << "\n";
    }

    template<typename Type>
    MimeLogger& operator<<(const Type& t)
    {
        oss_m << t;
        return *this;
    }
};


void LogDemo()
{       
   MimeLogger logger;
   logger << "Hello " << "World!!\n";
   MimeLogger() << "Hello " << "StackOverflow!!\n";
}
于 2012-05-16T00:20:41.043 に答える