在经历了各种STL算法的模板定义之后 查找 , 标准:相等 , std::计数 ,必须找到由类型为的对象组成的模板定义 输入迭代器 .那么它们是什么?为什么使用它们? 输入迭代器 是C++标准库中存在的五种主要迭代器之一,其他是 输出迭代器 , 前向迭代器 , 双向迭代器 , 和 随机访问迭代器 . 输入迭代器被认为是 最弱的 以及 简单的 在所有可用的迭代器中,基于它们的功能以及使用它们可以实现什么。它们是可以在顺序输入操作中使用的迭代器,迭代器指向的每个值只读一次,然后迭代器递增。
需要记住的一件重要事情是 向前地 , 双向的 和 随机存取 迭代器也是有效的输入迭代器,如上面的迭代器层次结构所示。
显著特征
- 可用性: 输入迭代器只能用于 单程算法 ,也就是说,在算法中,我们最多可以一次搜索范围内的所有位置,比如当我们必须搜索或找到范围内的任何元素时,我们最多只能搜索一次位置。
- 平等/不平等比较: 一个输入迭代器可以与另一个迭代器进行相等性比较。因为迭代器指向某个位置,所以两个迭代器只有在指向同一位置时才相等,否则就不相等。 因此,如果A和B是输入迭代器,则以下两个表达式有效:
A == B // Checking for equality A != B // Checking for inequality
3. 取消引用: 可以取消对输入迭代器的引用,使用运算符*和->作为右值,以获取存储在迭代器指向的位置的值。 因此,如果A是输入迭代器,以下两个表达式是有效的:
*A // Dereferencing using * A -> m // Accessing a member element m
4. 可递增: 输入迭代器可以递增,以便使用运算符++()引用序列中的下一个元素。
注: 我们可以将输入迭代器与增量运算符一起使用,这并不意味着运算符–-()也可以与它们一起使用。记住,输入迭代器是单向的,只能向前移动。 因此,如果A是输入迭代器,以下两个表达式是有效的:
A++ // Using post increment operator ++A // Using pre increment operator
可交换: 这些迭代器指向的值可以交换。
实际执行 在了解了它的特点和不足之后,了解它的实际实现也是非常重要的。如前所述,输入迭代器仅在我们想要访问元素时使用,而不是在我们必须为元素分配元素时使用。以下两种STL算法可以说明这一事实:
- std::查找: 正如我们所知,该算法用于查找容器中元素的存在。所以,让我们看看它的内部工作原理(不必详细说明,只需看看在哪里可以使用输入迭代器,在哪里不能使用输入迭代器):
CPP
// Definition of std::find() template InputIterator find (InputIterator first, InputIterator last, const T& val) { while (first!=last) { if (*first==val) return first; ++first; } return last; } |
- 这是输入迭代器的实际实现, 单程算法,我们只需要按顺序移动,访问元素并检查是否相等 和上面使用的第一个元素一样,在这里可以使用它们。还有更多这样的算法 标准:相等 , 标准:等_范围 和 计数。
- std::复制: 顾名思义,该算法用于将一个范围复制到另一个范围。现在,就访问元素而言,输入迭代器很好, 但一旦我们必须在另一个容器中分配元素,我们就不能使用这些输入迭代器 为此目的。
CPP
// Definition of std::copy() template OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { while (first != last) *result++ = *first++; return result; } |
- 在这里,由于结果是结果容器的迭代器,元素被分配到该容器,因此,我们不能使用输入迭代器,而是在其位置使用输出迭代器,而对于第一个只需要递增和访问的容器,我们使用了输入迭代器。
局限性 在研究了显著特征之后,还必须了解它的缺陷,这使得它成为所有迭代器中最弱的迭代器,以下几点提到了这一点:
- 仅访问,不分配: 最大的缺陷之一是 我们不能赋予任何价值 对于该迭代器指向的位置,它只能用于访问元素,而不能分配元素。
CPP
// C++ program to demonstrate input iterator #include <iostream> #include <vector> using namespace std; int main() { vector< int > v1 = { 1, 2, 3, 4, 5 }; // Declaring an iterator vector< int >::iterator i1; for (i1 = v1.begin(); i1 != v1.end(); ++i1) { // Accessing elements using iterator cout << (*i1) << " " ; } return 0; } |
输出:
1 2 3 4 5
上面是使用输入迭代器访问元素的示例,但是,如果我们执行以下操作:
*i1 = 7;
- 因此,这在输入迭代器中是不允许的。然而,如果你在上面的代码中尝试这个方法,它会起作用,因为向量在层次结构中返回的迭代器比输入迭代器高。 这一巨大缺陷正是许多算法喜欢的原因 复制 ,这需要将一个范围复制到另一个容器中 不能 对结果容器使用输入迭代器,因为我们不能用这样的迭代器为其赋值,而是使用输出迭代器。
- 不能递减: 就像我们可以使用运算符++()和输入迭代器来增加它们一样,我们不能减少它们。
If A is an input iterator, then A-- // Not allowed with input iterators
- 在多通道算法中使用: 由于它是单向的,只能向前移动,因此,这种迭代器不能用于多次传递算法,在这种算法中,我们需要多次处理容器。
- 关系运算符: 尽管输入迭代器可以与等式运算符(=)一起使用,但不能与其他关系运算符(如<=)一起使用。
If A and B are input iterators, then A == B // Allowed A <= B // Not Allowed
- 算术运算符: 与关系运算符类似,它们也不能与+、–等算术运算符一起使用。这意味着输入操作符只能朝一个方向移动,这个方向太向前,太顺序。
If A and B are input iterators, then A + 1 // Not allowed B - 2 // Not allowed
因此,上面的两个例子很好地说明了何时、何地、为什么以及如何实际使用输入迭代器。 本文由 辛格先生 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。