如何返回fstream(C ++ 0x)

时间:2011-01-28 07:24:30

标签: c++ c++11 fstream move-semantics return-value-optimization

我想我会直接进入它并从代码开始:

#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()”上做了“返回值优化”(RTO)。实际上,如果修改为以下内容:

int main()
{
    auto os = test("testfile");
    os << "Test1\n";
    auto os2 = std::move(os);
    os2 << "Test2\n";
}

我不再在输出中同时获得Test1和Test2。

问题是,类“test”不可复制,因此没有机会重复传输。我只是想能够从函数中返回它。我似乎能够与海湾合作委员会做到这一点。

我宁愿没有取消引用分配给stream的堆的智能指针,也不会重新打开文件,因为它目前无需执行这些操作。我只是觉得我的方法中有点“非标准”,所以做我所描述的标准方法会很棒。

3 个答案:

答案 0 :(得分:15)

我将在这里回答我自己的问题:

GCC C++0x Library Features页面中,查看项目27.9,内容如下:

  

27.9 - 基于文件的流 - 部分 - 缺少移动和交换操作

我想这可能是我与gcc的问题。

答案 1 :(得分:2)

问题在于:

test(test&& old) {};

这允许你从右值test构造一个新的test,是的,但它没有说明你的基础,它只是默认构造(没有打开的文件)。你想要的是这个:

test(test&& old) : std::ofstream(std::move(old)) {};

将流从old移动到基地。

答案 2 :(得分:0)

调用者是否需要知道您正在返回ofstream,或者返回streambuf更有意义,让调用者将其包装在流中?