Как вернуть fstream (C ++ 0x) - PullRequest
       84

Как вернуть fstream (C ++ 0x)

7 голосов
/ 28 января 2011

Думаю, я сразу начну с кода:

#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).

Но у меня плохое предчувствие, что это просто из-за того, что мой компилятор выполнил «Оптимизацию возвращаемого значения» (RTO) на «auto os = test ()». Действительно, если изменить следующее:

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

Я больше не получаю одновременно Test1 и Test2.

Дело в том, что класс "test" не копируется, поэтому нет вероятности дублирования ofstream. Я просто хочу иметь возможность вернуть его из функции. И я, кажется, могу сделать это с GCC.

Я бы предпочел не разыменовывать умные указатели в куче, выделенной из потока, или открывать файл заново, так как в настоящее время он работает без этих действий. Мне просто кажется, что я немного «нестандартен» в своем подходе, поэтому стандартный способ сделать то, что я описал, был бы великолепен.

Ответы [ 3 ]

15 голосов
/ 31 января 2011

Я собираюсь ответить на свой вопрос здесь:

На странице GCC C ++ 0x Library Features , посмотрите на пункт 27.9, который гласит:

27.9 - Потоки на основе файлов - Частично - Отсутствуют операции перемещения и обмена

Я думаю, что, вероятно, это проблема с gcc.

2 голосов
/ 28 января 2011

Проблема с этим:

test(test&& old) {};

Это позволяет вам создать новый test из значения test, да, но ничего не говорит о вашей базе, которая просто создается по умолчанию (нет открытого файла). То, что вы хотите, это:

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

Который переместит поток из old в базу.

0 голосов
/ 28 января 2011

Нужно ли вызывающей стороне знать, что вы возвращаете ofstream, или было бы более разумно вернуть streambuf и позволить вызывающей стороне обернуть его в поток?

...