Я пытаюсь узнать больше о работе библиотеки потоков ввода-вывода C++, расширив std::streambuf
. В качестве учебного эксперимента моя цель - просто создать настраиваемый поток, который направляет все выходные данные на std::cerr
. Это кажется достаточно простым:Расширение C++ ostream
#include <iostream>
using namespace std;
class my_ostreambuf : public std::streambuf
{
public:
protected:
std::streamsize xsputn(const char * s, std::streamsize n)
{
std::cerr << "Redirecting to cerr: " << s << std::endl;
return n;
}
};
int main()
{
my_ostreambuf buf;
std::ostream os(&buf);
os << "TEST";
}
Это похоже на работу, так как он печатает Redirecting to cerr: TEST
. Проблема в том, что он не работает, когда один символ (в отличие от строки) вставляется в поток через std::ostream::sputc
. Например:
int main()
{
my_ostreambuf buf;
std::ostream os(&buf);
os << "ABC"; // works
std::string s("TEST");
std::copy(s.begin(), s.end(), std::ostreambuf_iterator<char>(os)); // DOESN'T WORK
}
Проблема я думаю, что xsputn
не обрабатывает одного вставки символов. (Я думаю, sputc
не звонит xsputn
внутренне?) Но, оглядываясь на list of virtual protected functions в std::streambuf
, я не вижу никакой функции, которую я должен переопределить, которая управляет вставкой одного символа.
Итак, как я могу это сделать?
Так что обрабатывается 'sputc'? – 0x499602D2
@ 0x499602D2: 'sputc' записывает символ во внутренний буфер, поддерживаемый streambuf. Этот буфер очищается, когда он заполнен или когда используются манипуляторы 'endl' или' flush' (и в нескольких других случаях). Когда буфер сбрасывается, «переполнение» вызывается со следующим символом, который будет поступать в буфер, если он не был заполнен (или с «eof», если буфер очищается, когда он не заполнен). Идея состоит в том, что 'overflow' записывает содержимое буфера, плюс символ, переданный как аргумент (если не' eof'), фактическому адресату. (продолжение в следующем комментарии) – HighCommander4
@ 0x499602D2: Таким образом, работающая реализация streambuf может быть написана путем переопределения 'overflow'. 'xsputn' используется при выводе строки символов одновременно. Его реализация по умолчанию просто записывает каждый символ во внутренний буфер, как если бы 'sputc' (где в конечном итоге они будут обрабатываться' overflow'). Тем не менее, 'xsputn' может быть переопределен, делает что-то более эффективное, например, обходит буфер и записывает строку символов непосредственно в пункт назначения. – HighCommander4