Удобно скопировать std :: vectorдля ввода объекта потока (std :: istream) - PullRequest
7 голосов
/ 20 февраля 2012

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

Подпись выглядит так:

doSomething(const std::string& ...,
          const std::string& ...,
          std::istream& aData,
          const std::string& ...,
          const std::map<std::string, std::string>* ...,
          long ...,
          bool ...);

Так как я не могу изменить / изменить эту стороннюю библиотеку / функцию, я должен адаптироваться в "моем" коде. В месте вызова у меня есть std :: vector, который содержит данные, которые, как ожидается, будут переданы в объекте istream. В настоящее время я копирую вектор в поток, перебирая его и используя оператор << для копирования побайтно. </p>

Я сильно подозреваю, что может быть более эффективный / удобный способ, но до сих пор не нашел ничего полезного. Любая помощь / ваши мысли очень ценятся.

Лучший, JR

Ответы [ 2 ]

15 голосов
/ 20 февраля 2012

Вы можете использовать vector символов в качестве основного буфера для входного потока без копирования содержимого вектора:

std::vector<unsigned char> my_vec;
my_vec.push_back('a');
my_vec.push_back('b');
my_vec.push_back('c');
my_vec.push_back('\n');

// make an imput stream from my_vec
std::stringstream is;
is.rdbuf()->pubsetbuf(reinterpret_cast<char*>(&my_vec[0]), my_vec.size());

// dump the input stream into stdout
std::cout << is.rdbuf();

@ NeilKirk сообщает, что вышеуказанный метод использования pubsetbuf является непереносимым .

Одним из переносимых способов является использование библиотеки boost::iostreams. Вот как построить входной поток из вектора, не копируя его содержимое:

#include <iostream>
#include <vector>

#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>

int main() {
    std::vector<unsigned char> my_vec;
    my_vec.push_back('a');
    my_vec.push_back('b');
    my_vec.push_back('c');
    my_vec.push_back('\n');

    // Construct an input stream from the vector.
    boost::iostreams::array_source my_vec_source(reinterpret_cast<char*>(&my_vec[0]), my_vec.size());
    boost::iostreams::stream<boost::iostreams::array_source> is(my_vec_source);

    // Dump the input stream into stdout.
    std::cout << is.rdbuf();
}
7 голосов
/ 20 февраля 2012
vector<unsigned char> values;
// ...

stringstream ioss;    
copy(values.begin(), values.end(),
     ostream_iterator<unsigned char>(ioss,","));

// doSomething(a, b, ioss, d, e, f, g);
...