我知道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?
我如何避免这些资格?这似乎与使用迭代器完全不同。
答案 0 :(得分:3)
您标记了C ++ 11,因此要避免这些声明,您可以使用范围for-loop
在begin()
和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;