创建自己的迭代器 我正在努力学习C++,所以请原谅我,如果这个问题说明缺乏基础知识,你知道,事实上,我缺乏基础知识。

创建自己的迭代器 我正在努力学习C++,所以请原谅我,如果这个问题说明缺乏基础知识,你知道,事实上,我缺乏基础知识。,c++,iterator,C++,Iterator,我想了解如何为我创建的类创建迭代器 我有一个类“Shape”,它有一个点容器。 我有一个类'Piece',它引用一个形状并定义该形状的位置。 工件没有形状,它只是引用一个形状 我想让它看起来像是一个点的容器,这些点与它引用的形状相同,但是添加了工件位置的偏移量 我希望能够遍历工件的点,就像工件本身就是一个容器一样。我在附近读了一些书,没有发现任何对我有帮助的东西。如果有任何建议,我将不胜感激。/EDIT:我明白了,这里实际上需要一个自己的迭代器(我先误读了问题)。尽管如此,我还是让下面的代码保持

我想了解如何为我创建的类创建迭代器

我有一个类“Shape”,它有一个点容器。 我有一个类'Piece',它引用一个形状并定义该形状的位置。 工件没有形状,它只是引用一个形状

我想让它看起来像是一个点的容器,这些点与它引用的形状相同,但是添加了工件位置的偏移量


我希望能够遍历工件的点,就像工件本身就是一个容器一样。我在附近读了一些书,没有发现任何对我有帮助的东西。如果有任何建议,我将不胜感激。

/EDIT:我明白了,这里实际上需要一个自己的迭代器(我先误读了问题)。尽管如此,我还是让下面的代码保持不变,因为它在类似的情况下也很有用


这里真的需要自己的迭代器吗?也许将所有必需的定义转发到包含实际点的容器就足够了:

// Your class `Piece`
class Piece {
private:
    Shape m_shape;

public:

    typedef std::vector<Point>::iterator iterator;
    typedef std::vector<Point>::const_iterator const_iterator;

    iterator begin() { return m_shape.container.begin(); }

    const_iterator begin() const { return m_shape.container.begin(); }

    iterator end() { return m_shape.container.end(); }

    const_iterator end() const { return m_shape.const_container.end(); }
}
//你的班级`作品`
班级作品{
私人:
形状m_形;
公众:
typedef std::vector::迭代器迭代器;
typedef std::vector::const_迭代器const_迭代器;
迭代器begin(){返回m_shape.container.begin();}
常量迭代器begin()常量{返回m_shape.container.begin();}
迭代器end(){return m_shape.container.end();}
const_迭代器end()const{return m_shape.const_container.end();}
}

这是假设您在内部使用
向量,但类型可以轻松调整。

解决问题的方法不是创建自己的迭代器,而是使用现有的STL容器和迭代器。将每个形状中的点存储在类似向量的容器中

class Shape {
    private:
    vector <Point> points;
类形状{
私人:
矢量点;
从那时起,您要做什么取决于您的设计。最好的方法是迭代Shape中的方法中的点

for (vector <Point>::iterator i = points.begin(); i != points.end(); ++i)
    /* ... */
for(向量::迭代器i=points.begin();i!=points.end();++i)
/* ... */
如果需要访问形状以外的点(这可能是设计缺陷的标志),可以创建形状内方法,返回点的迭代器访问函数(在这种情况下,还可以为点容器创建公共typedef)。有关此方法的详细信息,请参阅Konrad Rudolph的答案。

您可以阅读此内容


基本上,从std::iterator继承来为您完成大部分工作。

您应该使用Boost.Iterators。它包含许多模板和概念,用于为现有迭代器实现新的迭代器和适配器。我已经写过;它在2008年12月的ACCU杂志上。它讨论了一个(IMO)针对您的问题的优雅解决方案:使用Boost.Iterators从对象公开成员集合

如果您只想使用stl,则有一章介绍如何实现您自己的stl迭代器。

这是一篇优秀的文章,解释了如何设计类似stl的容器类以及迭代器类的一些基本概念。不过,反向迭代器(稍微难一点)只是作为练习:-)


在C++中编写自定义迭代器的理解可以是冗长而复杂的。

因为我找不到编写自定义迭代器的最小方法,所以我编写了一个可能会有所帮助的迭代器。例如,要使
片段
类可伸缩:

#include <iostream>
#include <vector>

#include "iterator_tpl.h"

struct Point {
  int x;
  int y;
  Point() {}
  Point(int x, int y) : x(x), y(y) {}
  Point operator+(Point other) const {
    other.x += x;
    other.y += y;
    return other;
  }
};

struct Shape {
  std::vector<Point> vec;
};

struct Piece {
  Shape& shape;
  Point offset;
  Piece(Shape& shape, int x, int y) : shape(shape), offset(x,y) {}

  struct it_state {
    int pos;
    inline void next(const Piece* ref) { ++pos; }
    inline void begin(const Piece* ref) { pos = 0; }
    inline void end(const Piece* ref) { pos = ref->shape.vec.size(); }
    inline Point get(Piece* ref) { return ref->offset + ref->shape.vec[pos]; }
    inline bool cmp(const it_state& s) const { return pos != s.pos; }
  };
  SETUP_ITERATORS(Piece, Point, it_state);
};
#包括
#包括
#包括“iterator_tpl.h”
结构点{
int x;
int-y;
点(){}
点(intx,inty):x(x),y(y){
点运算符+(点其他)常量{
其他.x+=x;
其他。y+=y;
归还他人;
}
};
结构形状{
std::vec;
};
结构件{
形状&形状;
点偏移;
工件(形状和形状,int x,int y):形状(形状),偏移量(x,y){
结构it_状态{
int pos;
内联void next(常量块*ref){++pos;}
内联void begin(常数块*ref){pos=0;}
内联空心端(常数块*ref){pos=ref->shape.vec.size();}
内联点获取(工件*ref){return ref->offset+ref->shape.vec[pos];}
内联boolcmp(const it_state&s)const{return pos!=s.pos;}
};
设置迭代器(工件、点、it状态);
};
然后您可以将其用作普通STL容器:

int main() {
  Shape shape;
  shape.vec.emplace_back(1,2);
  shape.vec.emplace_back(2,3);
  shape.vec.emplace_back(3,4);

  Piece piece(shape, 1, 1);

  for (Point p : piece) {
    std::cout << p.x << " " << p.y << std::endl;
    // Output:
    // 2 3
    // 3 4
    // 4 5
  }

  return 0;
}
intmain(){
形状;
形状。向量安置(1,2);
形状。向量安置(2,3);
形状。向量安置(3,4);
工件(形状,1,1);
用于(p点:件){

std::可能他想对他的类使用STL算法或函数特性……最初的问题实际上是说工件容器的迭代器在返回值时应该修改这些值。这需要一个单独的迭代器,尽管它可能应该继承或以其他方式主要从原始值获得@gbjbaanb:我的代码的优点是它可以被STL算法使用。几年后,这仍然是google上的最佳结果之一……现在可以通过这样做来概括这一点:
auto begin()->decltype(m_shape.container.begin()){return m_shape.container.begin();}
发布示例代码将有助于描述您所做的事情,而不仅仅是简单的英文文本。创建自定义迭代器可能不是一个基本的顶级、中级迭代器,至少是这样。他仍然需要创建自己的迭代器,将对分段的请求转发到该分段中的形状。自定义迭代器是一个很好的工具,并且非常优雅只是使用一个小的注释:这本书讲述了C++标准库,而不是STL——这些不同,但却被混淆了很多(我也是有罪的),注意<代码> STD::迭代器< /C> >从C++ 17标记。