C ++迭代器概括 - 不同的容器,相同的类型

时间:2014-06-10 03:29:10

标签: c++ c++11 iterator

我知道C ++中的迭代器没有抽象基类,但我有一个特定的问题,我无法找到答案。在list::begin()的文档中,给出了迭代列表的示例:

std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it != mylist.end(); ++it)
  std::cout << ' ' << *it;
...

对于list::rbegin(),这是给出的:

std::cout << "mylist backwards:";
for (std::list<int>::reverse_iterator rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
  std::cout << ' ' << *rit;
...

我是否真的必须指定迭代器是列表迭代器 - std::list<int>::iterator?这意味着我不能在来自不同容器的相同类型(比如int)之间的迭代器之间进行推广?!而且,我真的要区分std :: list :: iterator和std :: list :: reverse_iterator吗?根据文档,它们都是ForwardIterators

我如何避免这些资格?这似乎与使用迭代器完全不同。

2 个答案:

答案 0 :(得分:3)

您标记了C ++ 11,因此要避免这些声明,您可以使用范围for-loopbegin()end()之间进行迭代:

std::cout << "mylist contains:";
for (auto item : mylist)
  std::cout << item << *it;

是的,您需要区分反向迭代器的情况,因为它们实际上是另一种类型的迭代器(在std::list上反向,这是一个双向链表,因此循环的输出将是确实不同。)

修改

避免为不同的容器或迭代器类型编写手工循环的STL方法是使用通用算法将一对迭代器作为它们的参数:

std::for_each (mylist.begin(), mylist.end(), myfunction);

因此,您可以将算法重用于任何类型的容器或迭代器,而无需重写代码。这些算法是模板,使用迭代器类型进行模板化,允许在某些情况下提供特化(例如,使用随机迭代器比使用前向迭代器更容易进行std :: sort)。

答案 1 :(得分:1)

使用auto,然后您不必提及容器的类型

for (auto it=mylist.begin(); it != mylist.end(); ++it)
  std::cout << ' ' << *it;

for (auto rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
  std::cout << ' ' << *rit;

或使用decltype

for (decltype(mylist)::iterator it=mylist.begin(); it != mylist.end(); ++it)
  std::cout << ' ' << *it;

for (decltype(mylist)::reverse_iterator rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
  std::cout << ' ' << *rit;

或使用基于范围的for

for(auto const& elem : mylist) 
  std::cout << ' ' << elem;

如果您使用Boost,您也可以将this functionality扩展到反向迭代器

for(auto const& elem : (mylist | boost::adaptors::reversed)) {
  std::cout << ' ' << elem;