将多个迭代器推进到同一个字符串流中

Advancing multiple iterators into the same stringstream

请查看这段代码

  std::istringstream s("abc");
  std::istreambuf_iterator<char> i1(s), i2(s);
  std::cout<< "i1 returns "<<*i1<<'\n'
           << "i2 returns "<<*i2<<'\n';
  ++i1;
  std::cout<<"after incrementing i1, but not i2\n"
           <<"i1 returns "<<*i1<<'\n'
           <<"i2 returns "<<*i2<<'\n';
  ++i2; // this makes the apparent value of *i2 to jump from 'a' to 'c'
  std::cout << "after incrementing i2, but not i1\n"
            << "i1 returns " << *i1 << '\n'
            << "i2 returns " << *i2 << '\n';

我得到了类似

的输出
a
a

b
b

c
c

这与我的预期完全不同,因为 i1 和 i2 是两个不同的迭代器。

有人帮我一个忙吗?

来自cppreference

std::istreambuf_iterator is a single-pass input iterator that reads successive characters from the std::basic_streambuf object for which it was constructed.

这里重要的部分是single-pass的特点:一个值一旦被读取,就不能再返回读取了。回想一下,例如,您可以将 std::istreambuf_iterator 用于 std::cin。如果您在程序中从 std::cin 读取,这意味着您可以交互输入字符 - 没有回头路(您必须将字节保存在 std::string 或类似的文件中才能实现)。

现在,当创建多个引用相同流对象的迭代器时,推进一个意味着读取一个字符 - 所有迭代器都可以看到该字符。这是由于迭代器的 single-pass 性质,另请参阅 operator*:

的文档

Reads a single character by calling sbuf_->sgetc() where sbuf_ is the stored pointer to the stream buffer.

显然,所有迭代器实例共享解除引用运算符使用的状态。