5

私はこの作業コードを変換することを考えました:

ofstream outfile("my_file.txt");
copy(v.begin(), v.end(), ostream_iterator<int>(outfile));

これに:

copy(v.begin(), v.end(), ostream_iterator<int>(ofstream("my_file.txt")));

言い換えれば、私は「匿名」または名前のないバージョンの ofstream オブジェクトを使用します。

2 つの質問:

(1) 2 回目の試行が失敗するのはなぜですか?

(2) 2 番目の試みは文体的にも優れていますか、それとも C++ ではすべてを明示的に名前を付けたままにしておく方がよいでしょうか? 私は、オブジェクトが常にオンザフライで作成される Python のバックグラウンドを持っています。

ありがとう!!

4

3 に答える 3

3

ostream_iterator<T>コンストラクターはストリーム オブジェクトへの非参照const 受け取りますが、一時オブジェクトはせいぜいconst参照として渡すことができます (少なくとも C++03 では)。この理由は、この質問でよく説明されています。

ところで、ここではストリームを渡す方法について多くの選択肢がありませんでした:const参照は意味をなさず (ストリームostream_iterator 変更する必要があります)、プレーンostreamはコピーできないため受け入れられません (スライスポリモーフィズムを殺します)。

Python では、常に参照カウント(およびガベージ コレクション) されたオブジェクトへの参照を処理しているため、オンザフライで構成/渡しを行うことができます。

C++ オブジェクトのセマンティックは根本的に異なります。オブジェクトオブジェクトであり、参照ではありません。Python のものと同様のセマンティックを取得するには、すべてのオブジェクトを で動的に割り当て、newそれらを でラップして渡す必要がありshared_ptr<T>ます。

C++では、すべてを明示的に名前を付けたままにしておく方が良いですか

必ずしもそうとは限りません - 一時的なものを作成するのは完全に正常ですが、一時的なものを使用してできることとできないこと、参照がそれらの寿命にどのように影響するかなどを認識しておく必要があります。

于 2013-02-28T01:58:38.190 に答える
0

C++ では、オンザフライでオブジェクトを作成することもよくありますが、所有権の問題に注意する必要があります。

問題ostream_iterator<int>(ofstream("my_file.txt"))は、一時オブジェクトがコンストラクターに渡されることですが、構築されたオブジェクトは一時オブジェクトostream_iteratorの責任の所有権を取得しません。ostream_iteratorも一時的でない場合、コードの次の行で無効な参照を保持し続けます。

ID 関数に渡すか、キャストすることで、これを回避する方法があります。しかし、永続変数でそのようなメカニズムを使用すると、ぶら下がり参照が作成されるという意味で、それらは一般的に安全性を犠牲にします。

参照によってリンクされた複数のオブジェクトがあり、コンテナーに含まれる関係がない場合、現在の C++ のベスト プラクティスは、一時オブジェクトではなく名前付きオブジェクトを使用することです。

これが気に入らない場合は、共有ポインターをより頻繁に使用することを選択できます。このパターンにより、所有権を複数の参照間で共有し、コンテナーを非表示にすることができます。しかし、これは iostream の一部ではなく、設計上の決定として、ここでは少し疑問があります。

于 2013-02-28T02:22:53.703 に答える
0

それを説明するコンパイラから次のエラーメッセージが表示されます。

std::ostream_iteratorのコンストラクターは非 const 参照を取ります。std::ofstream を取るコンストラクタのバージョンはありません。

Untitled 33.cpp:21: error: no matching function for call to ‘std::ostream_iterator<int, char, std::char_traits<char> >::ostream_iterator(std::ofstream)’
/usr/include/c++/4.2.1/bits/stream_iterator.h:185: note: candidates are: std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(const std::ostream_iterator<_Tp, _CharT, _Traits>&) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.2.1/bits/stream_iterator.h:181: note:                 std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(std::basic_ostream<_CharT, _Traits>&, const _CharT*) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
/usr/include/c++/4.2.1/bits/stream_iterator.h:169: note:                 std::ostream_iterator<_Tp, _CharT, _Traits>::ostream_iterator(std::basic_ostream<_CharT, _Traits>&) [with _Tp = int, _CharT = char, _Traits = std::char_traits<char>]
于 2013-02-28T02:01:52.790 に答える