2017-07-13 1 views
3

デバッグ出力をC++ 03プロジェクトに追加しようとしましたが、奇妙な結果がありました。 、いくつかの理由名前のないstd :: ofstreamへの文字列の出力が、なぜ私に16進数を与えるのですか?

#include <fstream> 

int main() 
{ 
    { 
     std::ofstream file("/tmp/test.txt"); 
     file << "hello" << " ... OK, this works\n"; 
    } 
    std::ofstream("/tmp/test.txt",std::ios_base::app) << "hello" 
                 << " ... no, I mean hello!\n"; 
} 

ここで私は、コンパイル後に何を得るのです:ここでは単純化されたテストコードだ

$ g++ test.cpp -o test && ./test && cat /tmp/test.txt 
hello ... OK, this works 
0x80487fe ... no, I mean hello! 

なぜ私は無名のstd::ofstreamオブジェクトに文字列を出力する場合には進数を得るのですか?そして、なぜ2番目の文字列の後続出力が機能するのですか?

+0

可能な重複:[std :: ostringstreamは、その内容の代わりにc-stringのアドレスを出力します。](https://stackoverflow.com/questions/8287188/stdostringstream-printing-the-address-of-the-c -string-of-its-content) – NathanOliver

答えて

8

我々はstd::ostreamにCの文字列を渡すために使用する通常のoperator<<declared asフリー機能

template< class Traits > 
basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>& os, 
             const char* s); 

ある無名のstd::ofstreamオブジェクトは、一時的な変数であり、一時はこのように、この、nonconst参照にバインドすることはできませんオペレータの過負荷は過負荷解決に関与しません。代わりに、最も近い一致は、タイプ消去ポインタを取り、単にその値を出力メンバ関数

std::basic_ostream& std::basic_ostream::operator<<(const void*); 

を取られます。メンバ関数は一時的なオブジェクトで呼び出すことができるので、この関数はうまくいきます。これは出力の16進数を説明します。今、この演算子は参照、std::basic_ostream&を返します。これはもはや一時オブジェクトではなく、非コンストオブジェクトへの参照であるため、operator<<の通常の自由関数オーバーロードはconst char*となり、正常に呼び出すことができます。これは、2番目の文字列が期待どおりに印刷される理由です。

template< class CharT, class Traits, class T > 
basic_ostream< CharT, Traits >& operator<<(basic_ostream<CharT,Traits>&& os, 
              const T& value); 

、一時は参照を右辺値に結合ん:期待通りC++ 11のコードは動作しますから、そこ以来、私たちは右辺値参照を取るoperator<<の追加のオーバーロードを、持っていることを

注意。

は、C++ 03のコードの作業を行うには、オブジェクトにnonconstの参照を返し、 fstreamオブジェクト上の任意のユーザに見える副作用はありませんメンバ関数 std::ostream::flush()を、使用することができます
#include <fstream> 

int main() 
{ 
    std::ofstream("/tmp/test.txt").flush() << "hello" 
              << " ... OK, this now works too\n"; 
} 
+0

明快にするために、ストリーム挿入子の一部はメンバ関数であり、いくつかはフリー関数であることに言及することもできます。一時関数で呼び出すことができるメンバ関数ですが、それはあなたが言及した最初の2つの違いです。 –

関連する問題