Context
Trying to create some gzip archive with a different filename inside I wrote this following snippet of code.
#include <iostream>
#include <utility>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filter/gzip.hpp>
boost::iostreams::filtering_ostream&& makeGZipStream(const std::string& archiveName,
const std::string& fileName)
{
boost::iostreams::filtering_ostream theGzipStream;
boost::iostreams::gzip_params theGzipParams;
theGzipParams.file_name = fileName;
theGzipStream.push(boost::iostreams::gzip_compressor{theGzipParams});
theGzipStream.push(boost::iostreams::file_sink{archiveName});
return std::move(theGzipStream);
}
int main()
{
boost::iostreams::filtering_ostream&& theGzipStream = makeGZipStream("archive.gz", "file");
theGzipStream << "This is a test..." << std::endl;
return 0;
}
Problem
This (as we may expect) produces a core dump because in makeGZipStream
we try to return a local stack-allocated variable by (rvalue-)reference. But the copy was not an option in this case as boost::iostreams::filtering_ostream
is non-copyable.
Questions
- We can return a
std::unique_ptr
"by value" thanks to its move constructor (and the move should not even occur in C++17 thanks to copy-elision), why isn't it possible in this case ? - What are the good solutions there ?
Possible solutions
- Putting everything in the same scope (what I was trying to avoid)
- Wrapping your object in a
unique_ptr
(not so pretty) - Anything else ?
Notes
The compiler used was the quite old g++ (GCC) 4.9.3
.