Cannot make std::unique_ptr<std::istream> hold a pointer to std::ifstream

191 views Asked by At

Consider the following piece of code (out of context for the sake of simplicity):

std::unique_ptr<std::istream> stream;
stream = std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary);

This code compiles just fine with MSVC and works with no problem, but Clang issues an error:

error: no viable overloaded '='
stream = std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary);

Alongside with the error above, the log also claims that 'unique_ptr<std::basic_ifstream<char>, default_delete<std::basic_ifstream<char>>>' is not convertable to 'unique_ptr<std::istream, default_delete<std::istream>>'.

I cannot use a reference as I need to keep stream alive outside the current scope, so a pointer seems to be the only solution. How can I solve the problem?

1

There are 1 answers

2
Cayin On
int maint() {
    // block
    {
        uint8_t buffer_size = 128;
        std::unique_ptr<char[]> buffer(new char[buffer_size]);
        memset(buffer.get(), 0, buffer_size);
        //// register unique_ptr to handle resource
        std::unique_ptr<std::ifstream, void(*)(std::ifstream *)>
                f(new std::ifstream(FILE_PATH, std::ios::in | std::ios::binary), [](std::ifstream *f) {
                    f->close(); // custom deleter
                });
        if (!f->is_open()) {
            return 0;
        }
        while (!f->eof()) {
            f->read(buffer.get(), buffer_size);
            std::cout << buffer.get() << std::endl;
        }
    } // trigger deleter to free resource
}