Удвоение потока - PullRequest
       0

Удвоение потока

5 голосов
/ 07 сентября 2011

Я использую поток cerr для вывода ошибок, но я также хотел сохранить любой из этих выводов ошибок в потоке строки в памяти.

Я хочу включить это:

stringstream errorString;
cerr << " Something went wrong ";
errorString << " Something went wrong ";

Into

myErr << " Something went wrong ";

Где myErr - это экземпляр класса, который хранит его в потоке строки и также выводит в cerr.

Спасибо за любую помощь.

Ответы [ 5 ]

3 голосов
/ 07 сентября 2011

Вы можете создать тип своего myErr класса следующим образом:

class stream_fork
{
    std::ostream& _a;
    std::ostream& _b;

public:
    stream_fork( std::ostream& a, std::ostream& b)
        :   _a( a ),
            _b( b )
    {
    }

    template<typename T>
    stream_fork& operator<<( const T& obj )
    {
        _a << obj;
        _b << obj;
        return *this;
    }

    // This lets std::endl work, too!
    stream_fork& operator<<( std::ostream& manip_func( std::ostream& ) )
    {
        _a << manip_func;
        _b << manip_func;
        return *this;
    }
};

Использование:

stream_fork myErr( std::cerr, errorString );
myErr << "Error Message" << std::endl;
2 голосов
/ 07 сентября 2011

Вы можете использовать Boost.IOStreams .

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <iostream>
#include <sstream>

namespace io = boost::iostreams;

int main() {
    std::stringstream ss;
    io::tee_device<decltype(ss), decltype(std::cerr)> sink(ss, std::cerr);
    io::stream<decltype(sink)> stream(sink);
    stream << "foo" << std::endl;
    std::cout << ss.str().length() << std::endl;
    return 0;
}
1 голос
/ 07 сентября 2011

Использование Повышение tee.

1 голос
/ 07 сентября 2011

Переопределить operator<< в вашем MyErr классе

MyErr& operator<< ( MyErr& myErr, std::string message)
{
    cerr << message;
    errorString << message; //Where errorString is a member of the MyErr class

    return myErr;
}

Тогда, где вы хотите записать ошибку:

int main()
{
    MyErr myErr;
    myErr << " Something went wrong. ";

    return 0;
}

Вы можете сделать MyErr одиночнымкласс, чтобы все, что записано в errorString, было в одном месте.

0 голосов
/ 07 сентября 2011

Вам необходимо создать подкласс streambuf и объявить myErr как ostream, который использует ваш подкласс. Заставьте функции ввода ничего не делать, а затем скопируйте функции вывода в любые потоки, которые вам нужны.

У меня был класс, который делал нечто подобное 12 лет назад, но потерял след. Я не смог найти хороший пример, но документы для streambuf могли бы стать отправной точкой. Сосредоточьтесь на защищенных функциях выхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...