2016-11-02 7 views
0

メソッドによって返された一時オブジェクトに対してビットシフト演算子を使用しようとすると、問題が発生します。一時的に演算子がオーバーロードされる

Logオブジェクトを一時的に作成し、ビットシフト演算子を使用して、std :: stringstreamオブジェクトに格納される値を追加します。

一時的に破壊すると、std :: stringstreamはその内容をダンプしますが、デストラクタは最初の文字列を追加する前に呼び出されます。

小さな例:

class LogEntry 
{ 
public: 
    LogEntry(int level) : m_level{level} 
    { 
    } 

    ~LogEntry() 
    { 
     // dump m_out on destruction 
     Widget(m_out.str()); 
    } 

    template <typename T> 
    LogEntry& operator<<(T& arg) 
    { 
     m_out << arg; 

     return *this; 
    } 

private: 
    std::stringstream m_out; 
    const int m_level; 
} 

そして、これは私がそれを使用する方法です:

LogEntry(LOG_LEVEL_DEFAULT) << "This is a string" << 1234; 

これまでのところ、デストラクタはメモリであることを意味し、ビットシフト演算子の前に呼び出されています内容をm_outに追加するときにすでに壊れています。

オペレータが一時的な破壊の前に呼び出されることを確実にする方法を知っている人はいますか?

+2

LogEntry entry(LOG_LEVEL_DEFAULT)<< "これは文字列です。" << 1234;は構文エラーです。あなたが入力する意味がはっきりしません。 – hvd

+0

コンパイルしません: 'error:expected '、' or ';'あなたの意図する使用行に「<<」トークンの前に。 –

+0

さて、コードを編集しました。私は私のIDEでPCにいないので、私は転記ミスを犯したと思います。私は今あなたが質問に対処できることを願っています。 – pabloxrl

答えて

2

コメントで@hvdと@Richard Crittenが指摘したように、コードはコンパイルされません。デストラクタが呼び出される前に

LogEntry(LOG_LEVEL_DEFAULT) << "This is a string" << 1234; 

そして、あなたがそうするならば、2つの事業者が呼び出されます:あなたが唯一の文に住んで一時変数を使用する場合は、次のような、それに名前を与えることなくそれを行うことができ。

しかし、別の問題があります。演算子< <(T & arg)は左辺値参照を入力として受け取りますが、1234は左辺値ではありません。この2番目の問題を解決するには、演算子を汎用の参照を引数として取るように演算子を変更することができます。演算子< <(T & & arg)。

+0

これは質問に答えようとしないので、回答として投稿されるべきではありません。あなたは一時的な破壊(質問の全体のポイント)をまったくカバーしません。コメントとしても役立つと思います。 – hvd

+0

@hvd私が与えたコードは、デストラクタの前に演算子を呼び出す。私はその声明を含める答えを更新しました。 –

+0

あなたは正しいと言いましたので、その質問に対する有効な回答であったはずです。営業担当者は、これが正確には機能しないと主張する質問を編集しました。 – hvd

関連する問題