我有一堆基于顶点实现几何对象的类,例如TriangleMesh,PointClouds或Edgesets。它们都继承自VertexBasedGeometry。我现在希望所有这些都在其顶点的引用上返回一个双向迭代器。这将允许以非模板化方式访问任何VertexBasedGeometry的顶点。现在,我对迭代器不是很熟悉,事实证明这很困难。我的尝试看起来如下:
class VertexBasedGeometry : public Geometry
{
public:
typedef std::iterator<std::bidirectional_iterator_tag,defines::Vector3 > VertexIterator;
VertexBasedGeometry(){};
virtual VertexIterator begin()=0;
virtual VertexIterator end()=0;
};
在继承自VertexBasedGeometry的TraingleMesh中,我现在尝试通过返回包含其顶点的std :: vector的begin迭代器来实现函数begin。这导致gcc 4.2(apple)上的以下编译器错误:
Mesh.cpp:25: error: conversion from '__gnu_cxx::__normal_iterator<defines::Vector<double, 3>*, std::vector<defines::Vector<double, 3>, std::allocator<defines::Vector<double, 3> > > >' to non-scalar type 'std::iterator<std::bidirectional_iterator_tag, defines::Vector<double, 3>, long int, defines::Vector<double, 3>*, defines::Vector<double, 3>&>' requested
我现在的问题是:为什么这不起作用,我应该如何更改才能使其正常工作? 阅读更多有关迭代器的信息,我有点觉得我无法找到任何双向迭代器的公共类型,是吗?有些类可能将它们的顶点存储在除std :: vector之外的容器中,其他类已经提供了(非符合stl的)迭代器,我想要适应我的常用类型。我愿意接受任何有关如何实施此建议的建议。
答案 0 :(得分:2)
std :: iterator只是您派生自的标记类,并且必须在编译时知道实现类的迭代器类型。如果要从迭代代码中隐藏迭代器实现,则必须添加间接级别,例如, Thomas Becker's any_iterator
答案 1 :(得分:1)
迭代器只是一个松散的概念,而真实的迭代器类在任何意义上都是无关的。通常,您不会为您的类编写完整的迭代器类。
迭代器确实具有某些共性,您必须设计它们以便可以使用std::iterator_traits
进行探测。这意味着任何给定的迭代器实现都会有很多类似的代码(像Boost的iterator facade这样的东西可能有帮助)。尽管如此,您的类的接口(如begin()
,end()
和find()
)必须返回您自己的迭代器类型,您必须编写迭代器的实现(即递增和解除引用运算符)。
答案 2 :(得分:0)
BidirectionalIterator
不是一个类,它是一个概念。概念由一组具有指定语义的需求和表达式组成。如果一个类满足概念的所有要求,那么它就被认为是这个概念的模型。这意味着某些概念的迭代器没有公共类,因为stdlib不能基于子类型多态而是基于概念。
那么std::iterator
是什么?它可以帮助您轻松定义特定迭代器的特性,但它不提供功能。它只支持编译时元编程。
有一些工具可以帮助您实现自己的类,这些类可以为Boost.Iterators这样的特定迭代器建模。