我正在编写一个C ++库来解析WARC文件,它包含用于存储WARC记录和字段数据的类以及用于从某些输入流中读取数据的运算符。它有operator>>
从istream
读取并填充WARCRecord
对象。我能够从istream
流中读取并将其解析为WARCRecord
对象。但是,我想使用istream_iterator
来读取输入流中的所有WARC记录。
当我使用istream_iterator
进行迭代直到流结束时,operator>>
接收到最后一次调用的相同(复制?)对象。这是预期的行为还是我在我的类定义中缺少一些运算符/构造函数?
这是带有单元测试的存储库链接,用于检查此行为:https://github.com/jvanz/libwarc
演示上述文字的简单示例:
#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <iterator>
class MyClass
{
public:
std::vector<unsigned int> fields;
friend std::istream& operator>> (std::istream& is, MyClass& obj);
};
std::istream& operator>> (std::istream& is, MyClass& obj){
std::istream::sentry s(is);
if (s) {
for (unsigned i = 0; i < 3; i++) {
unsigned f;
is >> f;
obj.fields.push_back(f);
}
}
return is;
}
int main(void)
{
std::stringstream ss;
ss << 1 << " " << 2 << " " << 3 << " " << 4 << " " << 5 << " " << 6;
std::istream_iterator<MyClass> it(ss);
std::cout << it->fields.size() << std::endl;
it++;
std::cout << it->fields.size() << std::endl;
return 0;
}
该程序的输出是:
$ ./a.out
3
6
注意fields
对象的MyClass
成员大小的累积
答案 0 :(得分:0)
我检查了我的计算机上的/usr/include/c++/7/bits/stream_operator.h
以查看istream_iterator
课程。事实上,据我所知,该类重用了同一个对象。
/// Provides input iterator semantics for streams.
template<typename _Tp, typename _CharT = char,
typename _Traits = char_traits<_CharT>, typename _Dist = ptrdiff_t>
class istream_iterator
: public iterator<input_iterator_tag, _Tp, _Dist, const _Tp*, const _Tp&>
{
public:
typedef _CharT char_type;
typedef _Traits traits_type;
typedef basic_istream<_CharT, _Traits> istream_type;
private:
istream_type* _M_stream;
_Tp _M_value;
bool _M_ok;
public:
/// Construct end of input stream iterator.
_GLIBCXX_CONSTEXPR istream_iterator()
: _M_stream(0), _M_value(), _M_ok(false) {}
/// Construct start of input stream iterator.
istream_iterator(istream_type& __s)
: _M_stream(std::__addressof(__s))
{ _M_read(); }
istream_iterator(const istream_iterator& __obj)
: _M_stream(__obj._M_stream), _M_value(__obj._M_value),
_M_ok(__obj._M_ok)
{ }
const _Tp&
operator*() const
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_deref_istream)
._M_iterator(*this));
return _M_value;
}
const _Tp*
operator->() const { return std::__addressof((operator*())); }
istream_iterator&
operator++()
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_inc_istream)
._M_iterator(*this));
_M_read();
return *this;
}
istream_iterator
operator++(int)
{
__glibcxx_requires_cond(_M_ok,
_M_message(__gnu_debug::__msg_inc_istream)
._M_iterator(*this));
istream_iterator __tmp = *this;
_M_read();
return __tmp;
}
bool
_M_equal(const istream_iterator& __x) const
{ return (_M_ok == __x._M_ok) && (!_M_ok || _M_stream == __x._M_stream); }
private:
void
_M_read()
{
_M_ok = (_M_stream && *_M_stream) ? true : false;
if (_M_ok)
{
*_M_stream >> _M_value;
_M_ok = *_M_stream ? true : false;
}
}
};
请注意_M_read()
在调用operator>>