[英]How does std::copy work with stream iterators
A usual STL construct is: 通常的STL结构是:
vector<string> col;
copy(istream_iterator<string>(cin), istream_iterator<string>(),
back_inserter(col));
where we use an istream_iterator
to copy from std input ( cin
) to a vector. 我们使用
istream_iterator
从std输入( cin
)复制到向量。
Can anyone explain how this code works? 谁能解释一下这段代码的工作原理
my problem is that I don't really understand this part: 我的问题是我真的不明白这一部分:
istream_iterator<string>(cin), istream_iterator<string>()
First, note that in this case, there's no real need to use std::copy
at all. 首先,请注意,在这种情况下,根本不需要使用
std::copy
。 You can just initialize the vector directly from the iterators: 您可以直接从迭代器初始化向量:
vector<string> col((istream_iterator<string>(cin)),
istream_iterator<string>());
This probably doesn't make the code a whole lot easier to understand though. 这可能不会使代码更容易理解。
As far as how the code works, it's probably a little more straighforward than you think. 至于代码如何工作,它可能比你想象的更直接。 An istream_iterator looks vaguely like this:
一个istream_iterator看起来像这样:
template <class T>
class istream_iterator {
std::istream *is;
T data;
public:
istream_iterator(std::istream &is) : is(&is) { ++(*this); }
istream_iterator() : is(nullptr) {}
T operator++() { (*is) >> data; return *this; }
T operator++(int) { (*is) >> data; return *this; }
T const &operator*() { return data; }
bool operator !=(istream_iterator &end) { return (*is).good(); }
bool operator ==(istream_iterator &end) { return !(*is).good(); }
};
Obviously there's more more I'm skipping over, but that's most of what we care about here. 显然,我正在跳过更多,但这是我们关心的大部分内容。 So, what happens is that when you create the iterator, it reads (or attempts to) an item from the stream into the variable I've called
data
. 因此,当您创建迭代器时,它会将流中的项读取(或尝试)到我称为
data
的变量中。 When you dereference the iterator, it returns data
. 取消引用迭代器时,它会返回
data
。 When you increment the iterator, it reads (or attempts to) the next item from the file. 当您递增迭代器时,它会读取(或尝试)文件中的下一个项目。 Despite being written as if they compare one iterator to another,
operator==
and operator!=
really just check for the end of the file 1 . 尽管编写好像将一个迭代器与另一个迭代器进行比较,但
operator==
和operator!=
实际上只是检查文件的结尾1 。
That's then used by std::copy
, which (again simplified) looks vaguely like this: 然后由
std::copy
,(再次简化)看起来像这样模糊:
template <class InIt, class OutIt>
void std::copy(InIt b, InIt e, OutIt d) {
while (b != e) {
*d = *b;
++b;
++d;
}
}
So, this reads and item from the input iterator, writes that item to the output iterator, and repeats until the iterator for the current position compares equal to the iterator for the end of the input (which will happen when you reach the end of the file). 因此,这将从输入迭代器读取和输入项,将该项写入输出迭代器,并重复直到当前位置的迭代器与输入结束的迭代器相比(当到达结束时将发生这种情况)文件)。 Note that unlike other iterators, the only "end" position you're allowed to use with an istream iterator is the end of the file.
请注意,与其他迭代器不同,您允许与istream迭代器一起使用的唯一“结束”位置是文件的末尾。
Part of the answer below is quoted from C++ standard library: A tutorial and reference by Nicolai M. Josuttis with a little tweaks. 以下部分答案引自C ++标准库:Nicolai M. Josuttis的教程和参考文章,稍作调整。
The expression
表达方式
istream_iterator<string>(cin)
creates a string iterator that reads from the standard input stream
cin
.创建一个从标准输入流
cin
读取的字符串迭代器。 The template argumentstring
specifies that the stream iterator reads elements of this type.模板参数
string
指定流迭代器读取此类型的元素。 These elements are read with the usual input operator >>.使用通常的输入运算符>>读取这些元素。 Thus, each time the algorithm wants to process the next element, the istream iterator transforms that desire into a call of
因此,每次算法想要处理下一个元素时,istream迭代器将该期望转换为调用
cin >> string
The input operator for strings usually reads one word separated by whitespaces.
字符串的输入运算符通常读取由空格分隔的一个单词。
The expression
表达方式
istream_iterator<string>()
calls the default constructor of the istream iterators that creates a so-called end-of-stream iterator.
调用istream迭代器的默认构造函数,它创建一个所谓的end-of-stream迭代器。 It represents a stream from which you can no longer read.
它表示您无法再读取的流。 The end-of-string iterator is used as the
end of the range
, so the algorithmcopy
reads all strings fromcin
until it can no longer read any more.字符串结束迭代器用作
end of the range
的end of the range
,因此算法copy
从cin
读取所有字符串,直到它不再能够读取为止。
The last one: 最后一个:
back_inserter(col))
according to back_inserter documentation: 根据back_inserter文档:
A std::back_insert_iterator which can be used to add elements to the end of the container c
一个std :: back_insert_iterator,可用于将元素添加到容器c的末尾
It will add all read in strings into col
. 它会将所有读入的字符串添加到
col
。
You can find information about std::istream_iterator and std::back_inserter for details. 有关详细信息,请参阅有关std :: istream_iterator和std :: back_inserter的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.