Search code examples
c++referenceglobal-variablesistream

Defining istream as global variable in main


I want to read compressed file in parallel. I need to define global istream (to pass its reference to read function). Here is my code.

#include <fstream>
#include <iostream>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/gzip.hpp>

std::istream &instream;

int main(int argc, char** argv) {

   std::ifstream file("test.gz", std::ios_base::in |std::ios_base::binary);
   boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
   inbuf.push(boost::iostreams::gzip_decompressor());
   inbuf.push(file);

   instream(&inbuf);
   //do something ...

   file.close();
}

I also tried this:

std::istream tmp(&inbuf);
instream = tmp;

Nothing seems to work. How can I initialize global istream variable inside main function?


Solution

  • You can derive from std::istream and attach a buffer:

    // Omitting boost in this example
    #include <iostream>
    
    class global_istream : public std::istream
    {
        public:
        global_istream() {};
    };
    
    // No reference
    global_istream instream;
    
    int main(int argc, char** argv) {
        // Attach a buffer to the global stream.
        // Any usage of instream before the buffer has been attached is fatal. 
        instream.rdbuf(std::cin.rdbuf());
        // In your case: instream.rdbuf(&inbuf);
    
        //do something ...
        std::string s;
        instream >> s;
        std::cout << s << '\n';
    
        // Detttach the buffer from the global stream.
        // Any usage of instream after the buffer has been detached is fatal. 
        instream.rdbuf(nullptr);
    }
    

    Maybe better, using a function:

    std::istream& instream()
    {
        static std::ifstream file("test.gz", std::ios_base::in |std::ios_base::binary);
        static boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
    
        auto setup_buffer = [] {
            inbuf.push(boost::iostreams::gzip_decompressor());
            inbuf.push(file);
            return &inbuf;
        };
    
        static std::istream instream(setup_buffer());
        return instream;
    }