Если вы собираетесь вернуть локальный поток из функции, то вам нужно как динамически выделить поток и его буфер. Как пояснили комментарии и ответ, вы возвращаете указатели на локальные переменные, которые будут уничтожены после выхода из функции. Стандартные потоковые классы std::istream
и std::ostream
не являются подвижными, поэтому единственный вариант - создать объекты в куче. И поток, и буфер могут быть обернуты в умный указатель, чтобы избежать ручного управления памятью.
std::unique_ptr<std::istream> getStreamFrom(std::string filepath) {
auto init_buf = std::make_unique<std::filebuf>();
return std::make_unique<std::istream>(
init_buf->open(filepath, std::ios_base::in)
? init_buf.release()->close()
: nullptr
);
}
Кстати, std::istream
, инициализированный std::filebuf
, равен std::fstream
. Вы также можете вернуть указатель на это:
std::unique_ptr<std::ifstream> getStreamFrom(std::string filepath) {
auto stream = std::make_unique<std::ifstream>(filepath);
stream->close();
return std::unique_ptr<std::ifstream>( *stream ? std::move(stream) : nullptr );
}
с необязательным в C ++ 17:
std::optional<std::ifstream> getStreamFrom(std::string filepath) {
std::ifstream stream(filepath);
stream.close();
return stream ? std::optional(std::move(stream)) : std::nullopt;
}