Search code examples
c++binaryfilespresetanonymous-objects

Writing/Reading from a binary file without having to declare a buffer variable - but via anonymous object


Currently, for writing to a binary file I'd write:

file.write((char*)&toWrite, sizeof(toWrite type));

And for reading from a binary file I'd write:

file.read((char*)&readInto, sizeof(readInto type));

But because of this method of reading/writing, presetting default values to a binary file (for insequential-reading/writing from/to the file) would require the use of a buffer variable with default values:

myType defaultValues; //defaultValues is initialized with
//myType's default constructor values
file.write((char*)&defaultValues, sizeof(myType));

I thought that via an anonymous object it would be possible in the following, shorter, form:

file.write((char*)&myType(), sizeof(myType)); //myType() is 
//an object which is initialized by myType's default constructor values

But because anonymous object's are not lvalues it's impossible.

Hence, the question is: Is there a way to shorten - by omitting the need to define a variable solely for the presetting of a binary file - the presetting of a binary file like I've done with anonymous object - just in a way that would actually work?


Solution

  • Currently, for writing to a binary file I'd write:

    file.write((char*)&toWrite, sizeof(toWrite type));
    

    Let me interrupt the question at this point to note that this is a bit redundant. The second parameter is completely determined by the first, so why should you have to write it out? Let's create a wrapper template for this to shorten your code. (It's up to what namespace this should go in, or maybe you want to give it a less-common name.)

    #include <iostream>
    #include <type_traits>
    
    template <class T>
    requires std::is_trivially_copyable_v<T>
    void write(std::ostream& out, const T& data) {
        out.write(reinterpret_cast<const char*>(&data), sizeof(T));
    }
    

    Now your writes are more simply

         write(file, toWrite);
    

    Note: The requires clause ensures that this template is used only when it is safe to do so. For example, this is not a safe way to write a std::string. Having the compiler check this is a benefit of this template. Other caveats for this approach still apply; it is not guaranteed to be portable across systems.

    Okay, let's get back to your question.

    But because anonymous object's are not lvalues it's impossible.

    Hmm... strange, but this is no longer a problem... Did I sabotage your question?