fstreamを返す方法(C ++ 0x)
-
26-10-2019 - |
質問
私はそれにすぐに入り、コードから始めます:
#include <iostream>
#include <fstream>
#include <string>
class test : public std::ofstream
{
public:
test(const std::string& filename) { this->open(gen_filename(filename)); };
test(const test&) = delete;
//test(test&& old) = default; // Didn't compile
test(test&& old) {};
private:
std::string gen_filename(const std::string& filename)
{ return filename + ".tmp"; }
};
int main()
{
auto os = test("testfile");
os << "Test1\n";
os << "Test2\n";
}
基本的に、私はOfstreamを返す必要があります。もちろん、Ofstreamをコピーすることはできないので、クラステストでコードをいじり回して、上記のコンパイルと作業を取得しました(GCC 4.5で)。
しかし、これは私のコンパイラが「Auto OS = test()」で「Return Value Optimization」(RTO)を行っていることによるものです。確かに、次のように変更する場合:
int main()
{
auto os = test("testfile");
os << "Test1\n";
auto os2 = std::move(os);
os2 << "Test2\n";
}
出力でtest1とtest2の両方を取得しなくなりました。
問題は、クラスの「テスト」がコピー可能ではないため、ofstreamが複製される可能性はないということです。関数から返すことができるようにしたいだけです。そして、私はGCCでそれを行うことができるようです。
むしろ、ストリームに割り当てられたヒープにスマートなポインターを繰り返したり、ファイルを再開したりすることは、現在機能していないためです。私は自分のアプローチで少し「標準以外」であると感じているので、私が説明したことをする標準的な方法は素晴らしいでしょう。
解決
ここで自分の質問に答えます:
の中に GCC C ++ 0xライブラリ機能 ページ、項目27.9をご覧ください。
27.9-ファイルベースのストリーム - 部分的 - 移動と交換操作の欠落
それはおそらく私がGCCで抱えている問題だと思います。
他のヒント
問題はこれにあります:
test(test&& old) {};
これにより、新しいものを構築できます test
rvalueから test
, 、はい、しかし、それはあなたのベースについて何も書いていません。それは単にデフォルトの構築されています(オープンファイルはありません)。あなたが望むのはこれです:
test(test&& old) : std::ofstream(std::move(old)) {};
ストリームをから移動します old
ベースに。
発信者はあなたが戻っていることを知る必要がありますか ofstream
, 、または、返す方が理にかなっているでしょう streambuf
, 、そして、発信者にストリーム内でそれを包みますか?