Подход к ограничению чтения из входных итераторов заключается в создании оболочки, которая подсчитывает количество обработанных элементов и конечный итератор которых сравнивается с этим числом. Делать это в общем не совсем тривиально, делать это специально для std::istream_iterator<T>
не должно быть слишком сложно. Тем не менее, я думаю, что самый простой способ сделать это это:
std::vector<T> buffer;
buffer.reserve(size);
std::istreambuf_iterator<T> it(in), end;
for (std::vector<T>::size_type count(0), capacity(size);
it != end && count != capacity; ++it, ++count) {
buffer.push_back(*it);
}
Я понимаю, что вы не хотите push_back()
, потому что это якобы медленно. Однако, по сравнению с операцией ввода-вывода, я сомневаюсь, что вы сможете измерить небольшие издержки, особенно с типичной реализацией библиотеки ввода-вывода.
Просто для округления на примере обернутого итератора: ниже приведен пример того, как может выглядеть оболочка подсчета для std::istream_iterator<T>
. Есть много разных способов сделать это, это только один из них.
#include <iostream>
#include <iterator>
#include <vector>
#include <sstream>
template <typename T>
class counted_istream_iterator:
public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t>
{
public:
explicit counted_istream_iterator(std::istream& in): count_(), it_(in) {}
explicit counted_istream_iterator(size_t count): count_(count), it_() {}
T const& operator*() { return *this->it_; }
T const* operator->() { return it_->it_.operator->(); }
counted_istream_iterator& operator++() {
++this->count_; ++this->it_; return *this;
}
counted_istream_iterator operator++(int) {
counted_istream_iterator rc(*this); ++*this; return rc;
}
bool operator== (counted_istream_iterator const& other) const {
return this->count_ == other.count_ || this->it_ == other.it_;
}
bool operator!= (counted_istream_iterator const& other) const {
return !(*this == other);
}
private:
std::ptrdiff_t count_;
std::istream_iterator<T> it_;
};
void read(int count)
{
std::istringstream in("0 1 2 3 4 5 6 7 8 9");
std::vector<int> vec;
vec.insert(vec.end(), counted_istream_iterator<int>(in),
counted_istream_iterator<int>(count));
std::cout << "size=" << vec.size() << "\n";
}
int main()
{
read(4);
read(100);
}