IT

나만의 반복자 만들기

lottoking 2020. 6. 21. 19:11
반응형

나만의 반복자 만들기


C ++을 배우려고 노력 중이므로이 질문에 기본 지식이 부족하다는 사실이 있으면 용서하십시오. 사실 기본 지식이 부족하다는 것을 알 수 있습니다.

내가 만든 클래스의 반복자를 만드는 방법에 대한 도움이 필요합니다.

Points 컨테이너가있는 'Shape'클래스가 있습니다. Shape를 참조하고 Shape의 위치를 ​​정의하는 'Piece'클래스가 있습니다. Piece에는 Shape가 없으며 단지 Shape를 참조합니다.

Piece가 참조하는 Shape의 컨테이너와 동일하지만 Piece의 위치 오프셋이 추가 된 Points의 컨테이너처럼 보입니다.

마치 Piece가 컨테이너 자체 인 것처럼 Piece의 Point를 반복 할 수 있기를 원합니다. 나는 약간의 독서를하고 나에게 도움이되는 것을 찾지 못했습니다. 나는 어떤 포인터에 대해서도 매우 감사 할 것입니다.


Boost.Iterators를 사용해야합니다. 여기에는 기존 반복기에 대한 새 반복기와 어댑터를 구현하기위한 많은 템플릿과 개념이 포함되어 있습니다. 나는이 주제에 관한 기사를 썼다 . 2008 년 12 월 ACCU 잡지에 있습니다. Boost.Iterators를 사용하여 객체에서 멤버 컬렉션을 노출시키는 정확한 문제에 대한 (IMO) 우아한 솔루션에 대해 설명합니다.

stl 만 사용하려면 Josuttis 책 에는 자체 STL 반복기 구현에 대한 장이 있습니다.


/ 편집 : 여기에 실제로 반복자가 필요하다는 것을 알았습니다 (먼저 질문을 잘못 읽었습니다). 여전히 비슷한 상황에서 유용 할 수 있기 때문에 아래 코드를 그대로 두었습니다.


여기에 자체 반복자가 실제로 필요합니까? 아마도 필요한 모든 정의를 실제 포인트를 보유하는 컨테이너에 전달하는 것으로 충분할 것입니다.

// 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(); }
}

이것은 vector내부적으로 사용한다고 가정 하지만 유형을 쉽게 조정할 수 있습니다.


여기서 사용자 정의 컨테이너와 같은 STL 디자인은 STL과 같은 컨테이너 클래스를 반복자 클래스와 함께 디자인하는 방법에 대한 몇 가지 기본 개념을 설명하는 훌륭한 기사입니다. 역행 반복자 (약간 힘들지만)는 운동으로 남아 있습니다 :-)

HTH,


기사를 읽을 수 있습니다

기본적으로 std :: iterator에서 상속하여 대부분의 작업을 수행합니다.


C ++로 커스텀 반복자를 작성하는 것은 이해하기에 장황하고 복잡 할 수 있습니다.

사용자 정의 반복자를 작성하는 최소한의 방법을 찾을 수 없으므로 도움이 될 수있는 이 템플릿 헤더작성 했습니다 . 예를 들어 Piece클래스를 반복 가능 하게 만들려면

#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);
};

그런 다음 일반 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;
}

또한 같은 반복자 다른 종류의 추가 할 수 있습니다 const_iterator또는 reverse_const_iterator.

도움이 되길 바랍니다.


문제에 대한 해결책은 자체 반복자를 작성하는 것이 아니라 기존 STL 컨테이너 및 반복자를 사용하는 것입니다. 벡터와 같은 컨테이너에 각 모양의 점을 저장하십시오.

class Shape {
    private:
    vector <Point> points;

그때부터하는 일은 디자인에 달려 있습니다. 가장 좋은 방법은 Shape 내부의 메서드에서 점을 반복하는 것입니다.

for (vector <Point>::iterator i = points.begin(); i != points.end(); ++i)
    /* ... */

If you need to access points outside Shape (this could be a mark of a deficient design) you can create in Shape methods that will return the iterator access functions for points (in that case also create a public typedef for the points container). Look at the answer by Konrad Rudolph for details of this approach.

참고URL : https://stackoverflow.com/questions/148540/creating-my-own-iterators

반응형