6

次のコードは、匿名ストリームと名前付きストリームの両方を含むファイルに文字列リテラルを出力します。

#include <fstream>

using namespace std;

int main()
{
    ofstream("testfile") << "test" << endl;

    ofstream ofs ("testfile2");
    ofs << "test2" << endl;

    return 0;
}

straceの出力からわかるように、名前付きストリームのみが機能します。

open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "0x400a91\n", 9)               = 9
close(3)                                = 0
open("testfile2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "test2\n", 6)                  = 6
close(3)                                = 0

また、リテラルの代わりにstd :: stringを使用すると、コンパイルに失敗します。

どうしてこれなの?

4

2 に答える 2

9

「匿名ストリーム」が右辺値であり、C++98ではメンバー関数しか呼び出せないという問題があります。は、ポインタのアドレスを出力するstream << "test"を取得するメンバーにバインドします。void*

C ++ 11にはoperator<<、右辺値ストリームを受け取るを追加しました。これにより、コードが機能します。

于 2012-09-18T16:38:30.947 に答える
4

C ++ 03では、文字ポインタと文字列を出力する非メンバー演算子は、左辺値参照を必要とするため、右辺値で呼び出すことはできません。そのため、メンバーoperator<<(const void *)が呼び出されます。C ++ 11では、これは右辺値参照を受け取るオーバーロードを記述することで解決されますが、C ++ 03では、左辺値参照を返すメンバー関数またはメンバー演算子を呼び出すことで回避できます(非定数メンバー関数右辺値で呼び出されます):

ofstream("testfile").write("", 0) << "test" << endl;

これを行うためのマニピュレータを簡単に作成できます。

std::ios_base& (*do_nothing)(std::ios_base&) ) {}

ofstream("testfile") << do_nothing << "test" << endl;
于 2012-09-18T16:56:04.220 に答える