2011-01-16 1 views
2
std::istream_iterator<std::string> ist(std::cin); 
std::istream_iterator<std::string> eof; 
std::vector<std::string> str_vec(ist, eof); 
std::ofstream ofs("a"); 
if (!ofs) { 
    throw std::runtime_error("Open file failed."); 
} 
std::ostream_iterator<std::string> ost(ofs, "\n"); 
for (size_t index = 0; index != str_vec.size(); ++index) { 
    //*ost = str_vec[index]; 
    *ost++ = str_vec[index]; 
} 

У меня такой же результат, независимо от того, я использую * ost ++ или нет. Я знаю значение приращения istream_iterator. Но в какой ситуации должен использоваться инкремент ostream_iterator?В какой ситуации следует использовать приращение ostream_iterator?

Спасибо!

ответ

2

Дальнейшие эксперименты могут показать, что вам даже не нужно разыгрывать итератор, чтобы заставить его работать. :)

ost = str_vec[index]; 

Все эти методы no-op необходимы, чтобы дать итераторам потока аналогичный интерфейс с другими итераторами.

Вместо ручного цикла вы можете использовать алгоритм std::copy. (Как это в значительной степени все ostream_iterator хорошо для, это бы-ответ на ваш вопрос: вам не нужно возиться с этими итераторы в собственном коде вообще)

std::copy(str_vec.begin(), str_vec.end(), std::ostream_iterator<std::string>(ofs, "\n")); 

Учитывая то, как функция копирования шаблон написан, может стать ясно, где приращения и разыменования необходимо:

template <class InIter, class OutIter> 
void copy(InIter begin, InIter end, OutIter result) 
{ 
    for (InIter it = begin; it != end; ++it) 
     *result++ = *it; // <-- here, result might be almost any kind of iterator 
} 
+0

Я больше понимаю, зачем использовать ostream_iterator. Спасибо за пример std :: copy. – MasterBeta

2

Оператор приращения, скорее всего, не работает для ostream_iterator, но он должен предоставить оператору соответствие требованиям выходных итераторов. Например, указатель является допустимым выходным итератором и должен быть увеличен.

+0

@Martin: См http://stdcxx.apache.org/doc/stdlibref/ostream-iterator.html#idx1067 –

+0

@Martin : Но речь идет о 'ostream_iterator', который является выходным итератором. Таким образом, ваш пример 'ost ++; ost ++; ost ++; ost ++' также является неопределенным поведением. –

+0

@ Фред Ларсон: Да, это совершенно неправильно. Попутно с вводом итератора ввода, объявленного первым в вопросе, и не увидев выходного итератора. –

1

Ваш алгоритм не должен увеличивать «итератор потока». Он должен увеличивать выходной итератор. Таким образом, всегда увеличивайте свой выходной итератор, если вы хотите вывести следующий элемент. Таким образом, ваш алгоритм будет поддерживать std::ostream_iterator, а также std::vector<T>::iterator и указатель T*. A std::ostream_iterator Приращение, скорее всего, будет no-op, но это не обязательно в случае с другими выходными итераторами.

Смежные вопросы