Your code is fine except for one small detail:
struct FileData { unique_ptr<char[]> buf; <del>unsigned int</del> <ins>streamoff</ins> len; };
The reason it does not compile for you is because your compiler does not yet implement the automatic creation of special relocation elements. In a fully C ++ 11 compiler, your FileData
will behave like this:
struct FileData { unique_ptr<char[]> buf; streamoff len; FileData(FileData&&) = default; FileData& operator=(FileData&&) = default; FileData(const FileData&) = delete; FileData& operator=(const FileData&) = delete; ~FileData() = default; };
The default move constructor simply moves the constructions of each member (and similarly for the default assignment for the move).
When d
returned from the LoadFile
, an implicit move occurs that will bind to the implicitly unlocked move constructor.
Using vector<char>
or string
, as others have suggested, will also work. But there is nothing wrong with your code as far as C ++ 11 is concerned.
Oh, I can configure it like this: I like to use my resources as quickly as possible:
FileData LoadFile(string filename) { ifstream str; str.open(filename, ios::binary); str.seekg(0, ios::end); auto len = str.tellg(); str.seekg(0, ios::beg); FileData d = {unique_ptr<char[]>(new char[len]), len}; str.read(d.buf.get(), d.len); str.close(); return d; }
If you need to explicitly define FileData
move elements, this should look like this:
struct FileData { unique_ptr<char[]> buf; streamoff len; FileData(FileData&& f) : buf(std::move(f.buf)), len(f.len) { f.len = 0; } FileData& operator=(FileData&& f) { buf = std::move(f.buf); len = f.len; f.len = 0; return *this; } };
Oh, which brings me to another point. By default, move elements do not match exactly , since they do not set len
to 0 in the source. It depends on your documentation if this is a mistake or not. ~FileData()
does not require len
to reflect the length of the buffer. But other customers can. If you have defined relocated from FileData
as not having a reliable len
, then the elements with the default, which were the default, are accurate, otherwise they will not.