所有双向迭代器的通用类类型,c++
我有一堆基于顶点实现几何对象的类,例如 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 。这会导致 gcc 4.2(苹果)上出现以下编译器错误:
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 的)迭代器,我想适应我的常见类型。我愿意接受任何关于如何实现这一点的建议。
I have a bunch of classes which implement geometric objects based on vertices, such as TriangleMesh, PointClouds or Edgesets. They all inherit from VertexBasedGeometry. I now want all of them to return a bidirectional iterator on references of its vertices. This would allow to access the vertices of any VertexBasedGeometry in a non-templated way. Now, me not being very familiar with iterators, this turns out to be rather difficult. My try looks as follows:
class VertexBasedGeometry : public Geometry
{
public:
typedef std::iterator<std::bidirectional_iterator_tag,defines::Vector3 > VertexIterator;
VertexBasedGeometry(){};
virtual VertexIterator begin()=0;
virtual VertexIterator end()=0;
};
In TraingleMesh, which inherits from VertexBasedGeometry I now try to implement the function begin by returning the begin iterator of the std::vector which contains its vertices. This results in the following compiler error on 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
My question are now: Why does this not work, and how should I change this to get it work?
Reading more about iterators, I got the slight feeling that I won't be able to find a common type for any bidirectional iterator, is that right? Some of the classes might have their vertices stored in containers other than std::vector, others already provide (non-stl-conforming ) iterators which I want to adapt to my common type. I am open for any recommendations how to implement this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
std::iterator 只是您派生自的标记类,并且实现类必须在编译时知道迭代器的类型。如果要在迭代代码中隐藏迭代器实现,则必须添加间接级别,例如 Thomas Becker 的任何_迭代器。
std::iterator is only a tag class that you derive from, and the type of your iterator must be known at compile-time to the implementing class. If you want to hide the iterator implementation from the iterating code, you must add an indirection level, e.g. Thomas Becker's any_iterator.
迭代器只是一个松散的概念,现实生活中的迭代器类在任何意义上都没有关联。一般来说,您无法为您的类编写完整的迭代器类。
迭代器确实具有某些共性,您必须设计它们,以便可以使用
std::iterator_traits
来探测它们。这意味着任何给定的迭代器实现都会有很多类似的代码(以及类似 Boost 的 迭代器门面 可能会有所帮助)。尽管如此,类的接口(例如begin()
、end()
和find()
)必须返回您自己的迭代器类型,并且您必须编写迭代器的实现(即递增和解引用运算符)。Iterators are only a loose concept, and real-life iterator classes aren't related in any sense. In general, you don't get around writing a complete iterator class for your class.
Iterators do share certain commonalities, and you have to design them so they can be probed with
std::iterator_traits
. This means that any given iterator implementation will have a lot of similar-looking code (and something like Boost's iterator facade may help). Nonetheless, your class's interface (likebegin()
,end()
andfind()
) will have to return your own iterator type, and you have to write the iterator's implementation (i.e. increment and dereference operators).Bi DirectionIterator
不是一个类,它是一个概念。概念由一组具有指定语义的需求和表达式组成。如果一个类满足某个概念的所有要求,则称其为该概念的模型。这意味着某些概念的迭代器没有通用类,因为 stdlib 不是基于子类型多态性而是基于概念工作。那么什么是 std::iterator 呢?它是一个帮助器,可以轻松定义特定迭代器的特征,但它不提供功能。它仅启用编译时元编程。
有一些工具可以帮助您实现自己的类来对特定迭代器进行建模,例如 Boost.Iterators。
BidirectionalIterator
is not a class, it is a concept. A concept consists of a set of requirements and expressions with specified semantics. If a class fulfills all requirements of a concept it is said to be a model of this concept. That means that there is no common class for iterators of some concept as the stdlib doesn't work based on subtype polymorphism but on concepts.So what is
std::iterator
? It's a helper to ease defining the traits of a specific iterator but it doesn't supply functionality. It only enables compile time meta-programming.There are a few tools that help you implement your own classes that model a specific iterator like the Boost.Iterators.