C++ 创建我自己的迭代器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/148540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating my own Iterators
提问by Howard May
I'm trying to learn C++ so forgive me if this question demonstrates a lack of basic knowledge, you see, the fact is, I have a lack of basic knowledge.
我正在尝试学习 C++,所以如果这个问题表明缺乏基础知识,请原谅我,你看,事实是,我缺乏基础知识。
I want some help working out how to create an iterator for a class I have created.
我需要一些帮助来解决如何为我创建的类创建迭代器。
I have a class 'Shape' which has a container of Points. I have a class 'Piece' which references a Shape and defines a position for the Shape. Piece does not have a Shape it just references a Shape.
我有一个“形状”类,它有一个点的容器。我有一个类'Piece',它引用一个形状并定义形状的位置。Piece 没有 Shape,它只是引用了一个 Shape。
I want it to seem like Piece is a container of Points which are the same as those of the Shape it references but with the offset of the Piece's position added.
我希望它看起来像 Piece 是一个点的容器,它与它引用的 Shape 相同,但添加了 Piece 位置的偏移量。
I want to be able to iterate through the Piece's Points just as if Piece was a container itself. I've done a little reading around and haven't found anything which has helped me. I would be very grateful for any pointers.
我希望能够遍历 Piece 的点,就像 Piece 本身就是一个容器一样。我已经做了一些阅读,但没有找到任何对我有帮助的东西。我将非常感谢任何指点。
采纳答案by Roel
You should use Boost.Iterators. It contains a number of templates and concepts to implement new iterators and adapters for existing iterators. I have written an article about this very topic; it's in the December 2008 ACCU magazine. It discusses an (IMO) elegant solution for exactly your problem: exposing member collections from an object, using Boost.Iterators.
你应该使用 Boost.Iterators。它包含许多模板和概念,用于为现有迭代器实现新的迭代器和适配器。我写了一篇关于这个主题的文章;它在 2008 年 12 月的 ACCU 杂志上。它针对您的问题讨论了一个(IMO)优雅的解决方案:使用 Boost.Iterators 从对象中公开成员集合。
If you want to use the stl only, the Josuttis bookhas a chapter on implementing your own STL iterators.
如果您只想使用 stl,Josuttis 书中有一章关于实现您自己的 STL 迭代器。
回答by Konrad Rudolph
/EDIT: I see, an own iterator is actually necessary here (I misread the question first). Still, I'm letting the code below stand because it can be useful in similar circumstances.
/编辑:我明白了,这里实际上需要一个自己的迭代器(我首先误读了这个问题)。尽管如此,我还是保留下面的代码,因为它在类似情况下很有用。
Is an own iterator actually necessary here? Perhaps it's sufficient to forward all required definitions to the container holding the actual Points:
这里真的需要一个自己的迭代器吗?也许将所有必需的定义转发到包含实际 Points 的容器就足够了:
// 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(); }
}
This is assuming you're using a vector
internally but the type can easily be adapted.
这是假设您在vector
内部使用 a但该类型可以轻松调整。
回答by Abhay
Here Designing a STL like Custom Containeris an excellent article which explains some of the basic concepts of how an STL like container class can be designed along with the iterator class for it. Reverse iterator (little tougher) though is left as an exercise :-)
此处设计类似自定义容器的 STL是一篇出色的文章,它解释了有关如何设计类似 STL 的容器类及其迭代器类的一些基本概念。反向迭代器(有点困难)虽然作为练习留下了:-)
HTH,
哈,
回答by gbjbaanb
You can read this ddj article
您可以阅读这篇ddj 文章
Basically, inherit from std::iterator to get most of the work done for you.
基本上,从 std::iterator 继承来为您完成大部分工作。
回答by VinGarcia
Writing custom iterators in C++ can be quite verbose and complex to understand.
用 C++ 编写自定义迭代器可能非常冗长且难以理解。
Since I could not find a minimal way to write a custom iterator I wrote this template headerthat might help. For example, to make the Piece
class iterable:
由于我找不到编写自定义迭代器的最小方法,因此我编写了这个可能有帮助的模板标头。例如,要使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);
};
Then you would be able to use it as a normal STL Container:
然后你就可以将它用作普通的 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;
}
It also allows for adding other types of iterators like const_iterator
or reverse_const_iterator
.
它还允许添加其他类型的迭代器,如const_iterator
或reverse_const_iterator
。
I hope it helps.
我希望它有帮助。
回答by Diomidis Spinellis
The solution to your problem is not the creation of your own iterators, but the use of existing STL containers and iterators. Store the points in each shape in a container like vector.
您的问题的解决方案不是创建您自己的迭代器,而是使用现有的 STL 容器和迭代器。将每个形状中的点存储在像向量这样的容器中。
class Shape {
private:
vector <Point> points;
What you do from then on depends on your design. The best approach is to iterate through points in methods inside Shape.
你从那时起做什么取决于你的设计。最好的方法是遍历 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.
如果您需要访问 Shape 之外的点(这可能是设计缺陷的标志),您可以在 Shape 方法中创建,该方法将返回点的迭代器访问函数(在这种情况下,还为点容器创建一个公共 typedef)。有关此方法的详细信息,请查看 Konrad Rudolph 的答案。