Search code examples
c++ofstreamostream

Custom ostream prints only last string of `<<` chain


I'm trying to implement a class with a custom stream operator, and inherits from it in order to have a base class and a derived one with different streams. Then I overload the << operator for using stored ostream.

This is a working sample of the code:

#include <string>
#include <memory>
#include <ostream>
#include <iostream>#
#include <fstream>

class Sink {
public:
    Sink() {
        m_stream = std::unique_ptr<std::ostream>(new std::ostream(std::cout.rdbuf()));
    };

    template<typename T>
    std::ostream& operator<<(const T& obj) {
        return *m_stream;
    }

protected:

    std::unique_ptr<std::ostream> m_stream;
};

class FileSink : public Sink {
public:

    FileSink() {
        m_stream = std::unique_ptr<std::ostream>(new std::ofstream("file.txt"));
    }
};

int main() {
    Sink s;
    FileSink fs;
    s << "First console string " << "second console string";
    fs << "First file string " << "second file string";
    return 0;
}

With the Sink class I write on console, with FileSink on a file.

The problem is that with this code I print only last string of every instruction.

In the console I see following output:

second console string

while in the file I can see this output:

second file string

What I'm doing wrong and how can I print the expected output?


Solution

  • Your operator<< does nothing and returns std::ostream&. Then you apply std::ostream::operator<< to that std::ostream&. Expected thing!

    Standard way to do what you want:

    template<typename T>
    Sink & Sink::operator<<(const T& obj) {
        *m_stream << obj;
        return *this;
    }
    template<typename T>
    FileSink & FileSink::operator<<(const T& obj) {
        *m_stream << obj;
        return *this;
    }
    

    To prevent code duplication you can use inheritance. It may duplicate std::stream inheritance scheme, I think. : )