C ++ iostreams вопрос - PullRequest
       7

C ++ iostreams вопрос

4 голосов
/ 24 июня 2010

Сейчас я углубляюсь в boost::iostreams и ищу способ создания потока, который повторяется по некоторым container<char>.

. Сейчас у меня есть код, который работает для std::vector<char>, но он делает ТОЛЬКО для него, , потому что я написал std::vector -специфический код.

Я делаю следующее:

template <class Object, class Container>
void Load(Object& object, const Container& container) {

   using namespace boost::iostreams;

   // Create a stream that iterates over vector and use it in
   // the following procedure
   LoadImpl(object, stream<array_source>(&container[0], container.size()));
}

, где LoadImpl(...) описывается следующим образом:

template <class Object
void LoadImpl(Object& object, std::istream& stream) { ... }

и используется для обертывания сериализации / десериализации с использованием некоторого определенного stream.

Не могли бы вы дать мне любойсовет, как сделать Load рутину более общей?Допустим, я хотел бы иметь возможность заменить std::vector<char> на него так же, как какой-нибудь контейнер std::string.

Ответы [ 3 ]

3 голосов
/ 24 июня 2010

Вместо передачи контейнера в качестве параметра вашим функциям, как насчет использования подхода, принятого стандартной библиотекой, и использования итераторов?

Ваша функция будет основана на типе итератора, а не на типе контейнера, и вместо контейнера будет использоваться начальный и конечный итератор. Тогда очень просто перебрать диапазон для любого типа контейнера, который вы ему предоставите.

1 голос
/ 25 июня 2010

Я бы посоветовал вам взглянуть на возможности, предоставляемые стандартной библиотекой.
Он имеет целый ряд адаптеров итераторов, которые помогают вам манипулировать контейнерами.

// Copy a stream into a vector
std::vector<char>  vec;    // This could be any container the
                           // code below would still work.
std::copy(std::istreambuf_iterator<char>(std::cin),
          std::istreambuf_iterator<char>(),
          std::back_inserter(vec)
         );

Это не просто итераторы, а служебные методы, которые вы используете для создания итераторов, которые просто превращают все это в простую мечту.

1 голос
/ 25 июня 2010

Прямой ответ - не использовать итераторы.Я думаю, что люди до меня не поняли, что это вопрос boost :: iostreams.

Я не эксперт по boost :: iostreams, но ваша процедура Load уже несколько общая и должна работать с std:: string (при условии, что вы заранее изменили его размер, чтобы сохранить буфер потока).Однако, используя устройство array_source, я полагаю, что вы исходите из предположения, что контейнер доступен случайным образом.Это не будет работать для std :: list, например.Для этого я не уверен, какое устройство подходит, но нужно другое, которое работает с использованием итераторов.

...