Как я могу расширить std :: basic_streambuf для обработки любой итерируемой последовательности как потока? - PullRequest
0 голосов
/ 04 февраля 2010

Примечание. Отредактировано на основе ответов для получения более подходящих ответов.

У меня есть коллекция шаблонов C ++, которые я делал на протяжении многих лет и называю Joop. Он состоит в основном из библиотек, которые не совсем попадают в категорию «общего назначения», но достаточно полезны, так что я продолжаю добавлять их в разные проекты, поэтому большинство из них не имеют эквивалентов в других библиотеках, таких как Boost. *

Один из этих классов seqstream. Идея состоит в том, что он позволяет вам обрабатывать любую итеративную последовательность как обычный STL-подобный поток, чей «тип символа» является типом значения последовательности.

Обоснование этого класса двоякое. Во-первых, он должен представлять интерфейс, который делает любую потенциально нелинейную, несмежную последовательность выглядеть линейной и смежной; и во-вторых, он должен обрабатывать любой объект в потоке, как если бы он был одним сложным крупным символом. Существует стандартное средство обработки потока как последовательности, так почему бы не наоборот?

В настоящее время seqstream включает три итератора для первого, последнего и текущего элемента. Я хочу заменить seqstream на basic_seqbuf, который можно подключить к стандартному потоку. Может ли кто-нибудь предоставить ресурсы, чтобы я начал расширять std::basic_streambuf, чтобы обеспечить такое поведение?

Кроме того, если разрешена запись seqbuf, то при записи объекта в seqbuf не сериализуется объект, но выполняется соответствующий вызов метода insert() или использует указанный пользователем итератор вставки, например std::back_insert_iterator.

Edit:

Вот пример того, как seqstream используется в настоящее время:

// Create a sequence of objects.
std::vector<std::string> sequence;
for (int i = 0; i < 10; ++i) {
    std::ostringstream stream;
    stream << "Element " << i << ".";
    sequence.push_back(stream.str());
}

// Create a seqstream wrapping that sequence.
joop::seqstream< std::vector<std::string> > seqstream(sequence.begin(), sequence.end());

// Read the sequence like a stream.
std::string element;
while (seqstream >> element) // OR seqstream.get(element)
    std::cout << element << '\n';

1 Ответ

1 голос
/ 04 февраля 2010

Просмотр примеров в sstream может быть затруднительным, но вам, вероятно, совсем не нужен новый класс потока. Теперь рассмотрим пример источника basic_stringstream, единственное назначение этого класса -

  • предоставляет str функцию (она просто вызывает базовый буфер str)
  • избегать vtable основного буфера при вызове его методов
  • изменить возвращаемое значение rdbuf на basic_stringbuf* (но в этом нет необходимости, поскольку был предоставлен метод доступа для str)

Потоковые классы делают очень мало и на самом деле не должны иметь никаких функций, кроме вызова базового буфера типа basic_streambuf. Например, я могу сделать это:

string str( "Hello, world!" );
stringbuf buf( str ); // subclass of basic_streambuf
iostream pseudo_stringstream( &buf );
    // pseudo_stringstream can do anything a stringstream can do.
    // (not necessarily with the same syntax)

Более того, все потоки должны наследоваться от basic_istream, basic_ostream или от обоих. Функции вставки / извлечения могут не работать, если ваш поток не наследуется правильно. Эти объявления вставки прекрасно подходят:

operator<<( ostream os, MyData d ); // not a template at all
       // templated, but requires correct inheritance:
template< class C > operator<<( basic_ostream<C> os, MyData d );

Поэтому, если вам нужно поведение iostream, вам нужно реализовать подкласс basic_streambuf и присоединить его к basic_iostream.


Но какова ваша настоящая цель? В чем преимущество потока с памятью перед обычными итераторами и, возможно, некоторыми back_insert_iterator с? Вы хотите использовать тот же код для сериализации, что и для итерации? Возможно, вы хотите, чтобы поток выглядел как последовательность, используя stream_iterator, а не чтобы последовательность выглядела как поток.

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