2

我有一堆基于顶点实现几何对象的类,例如 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 的开始迭代器来实现函数开始。这会在 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-conforming )迭代器,我想适应我的常见类型。我愿意接受任何关于如何实施这一点的建议。

4

3 回答 3

2

std::iterator 只是您从中派生的标记类,并且您的迭代器的类型必须在编译时为实现类所知。如果你想从迭代代码中隐藏迭代器实现,你必须添加一个间接级别,例如Thomas Becker 的 any_iterator

于 2011-10-06T11:47:40.520 回答
1

迭代器只是一个松散的概念,现实生活中的迭代器类在任何意义上都没有关联。通常,您不会为自己的类编写一个完整的迭代器类。

迭代器确实具有某些共性,您必须设计它们以便可以使用std::iterator_traits. 这意味着任何给定的迭代器实现都会有很多看起来相似的代码(像 Boost 的迭代器外观可能会有所帮助)。尽管如此,您的类的接口(如begin()和)必须返回您自己的迭代器类型,并且end()必须编写迭代器的实现(即递增和取消引用运算符)。find()

于 2011-10-06T12:31:49.097 回答
0

BidirectionalIterator不是一个类,它是一个概念。一个概念由一组具有特定语义的需求和表达式组成。如果一个类满足一个概念的所有要求,它就被称为这个概念的模型。这意味着某些概念的迭代器没有通用类,因为标准库不是基于子类型多态性而是基于概念。

那么是什么std::iterator?它可以帮助轻松定义特定迭代器的特征,但它不提供功能。它只启用编译时元编程。

有一些工具可以帮助您实现自己的类,这些类对特定的迭代器(如Boost.Iterators )进行建模。

于 2011-10-06T12:41:11.763 回答