从向量中获取通用的双向迭代器

5
在编写一个接收通用双向迭代器的函数之前,我想先测试它在整数向量上的工作原理。
vector<int> a(10,1);
iterator<bidirectional_iterator_tag, int> i = a.begin();
for (; i != a.end(); ++i) cout << *i;

这段代码无法编译。g++报错称无法将begin()的返回类型转换为iterator<bidirectional_iterator_tag, int>,并且在其上未定义++*运算符。显然我做错了什么,希望得到帮助。


这篇文章可能会很有趣。 - juanchopanza
1个回答

6
尽管std::iterator是一个基类,可以更轻松地实现新迭代器,但并不是所有迭代器都使用它,也不是所有迭代器都转换为它。唯一的要求是迭代器类必须提供一组指定的操作。这没有意味着存在类层次结构,并且大多数容器都包含自己的迭代器类。因此,在这种情况下,您应该将vector<int>::iterator作为您的迭代器类型。或者,如果您使用最新的C++11标准,可以使用auto让编译器推断类型。

4
@san,能否提供一个模板?当然,您需要确保传递的迭代器具有您所需的能力。 - chris
2
STL的方法是将迭代器传递给模板。您可以创建一个包装器层次结构,其中有一个抽象模板“basic_iterator<int>”提供公共接口,并将其用作“concrete_iterator<std::vector<int>::iterator>”模板的基类来包装STL迭代器。这样做,您将把编译时鸭子类型转换为运行时多态性。在大多数情况下,这会损失性能,但可能会节省内存,因为您可能需要较少的特化。您仍然需要将事物作为引用传递以保留多态性。 - MvG
@chris 如果你能向我展示如何做,我会很高兴给你点赞。我的想法是将iterator<bidirectional_iteratir_tag, V>作为输入参数的类型,这样在除迭代器以外的任何东西上调用它都会引发错误消息。但现在我意识到这将禁止许多合法的迭代器。 - san
1
如果您想检查某个对象是否为迭代器,可以使用 iterator_traits 和一些形式的静态断言。 (C++ 在核心语言中提供了它们,boost 提供了可移植机制。) - MvG
@MvG,说得好。我忘记用static_assert了。 - chris
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接