我有一个类TContainer,它是指向TItems类的几个stl集合指针的集合.
我需要创建一个迭代器来遍历我的TContainer类中所有集合中的元素,从而抽象出内部工作的客户端.
这样做有什么好办法?我应该创建一个扩展迭代器的类(如果是这样,我应该扩展什么迭代器类),我应该创建一个迭代器类,它是迭代器的集合吗?
我只需要一个FORWARD_ONLY迭代器.
IE,如果这是我的容器:
typedef std::vector <TItem*> ItemVector;
class TContainer {
std::vector <ItemVector *> m_Items;
};
Run Code Online (Sandbox Code Playgroud)
遍历m_Items成员变量向量中包含的所有项的好迭代器是什么.
Mar*_*ork 31
当我做自己的迭代器(前一段时间)时,我继承自std :: iterator并将该类型指定为第一个模板参数.希望有所帮助.
对于前向迭代器,请使用以下代码中的forward_iterator_tag而不是input_iterator_tag.
这个类最初来自istream_iterator类(并且我自己修改了它,因此它可能不再像istram_iterator那样).
template<typename T>
class <PLOP>_iterator
:public std::iterator<std::input_iterator_tag, // type of iterator
T,ptrdiff_t,const T*,const T&> // Info about iterator
{
public:
const T& operator*() const;
const T* operator->() const;
<PLOP>__iterator& operator++();
<PLOP>__iterator operator++(int);
bool equal(<PLOP>__iterator const& rhs) const;
};
template<typename T>
inline bool operator==(<PLOP>__iterator<T> const& lhs,<PLOP>__iterator<T> const& rhs)
{
return lhs.equal(rhs);
}
Run Code Online (Sandbox Code Playgroud)
请查看有关迭代器标记的文档:http:
//www.sgi.com/tech/stl/iterator_tags.html
刚刚重新阅读有关迭代器的信息:http:
//www.sgi.com/tech/stl/iterator_traits.html
这是旧的处理方式(iterator_tags),更现代的方法是为迭代器设置iterator_traits <>,使其与STL完全兼容.
Man*_*uel 18
首先让我们概括一下:
typedef int value_type;
typedef std::vector<value_type*> inner_range;
typedef std::vector<inner_range*> outer_range;
Run Code Online (Sandbox Code Playgroud)
现在迭代器:
struct my_iterator : std::iterator_traits<inner_range::iterator>
{
typedef std::forward_iterator_tag iterator_category;
my_iterator(outer_range::iterator const & outer_iterator,
outer_range::iterator const & outer_end)
: outer_iterator(outer_iterator), outer_end(outer_end)
{
update();
}
my_iterator & operator++()
{
++inner_iterator;
if(inner_iterator == inner_end)
{
++outer_iterator;
update();
}
return *this;
}
reference operator*() const
{
return *inner_iterator;
}
bool operator==(my_iterator const & rhs) const
{
bool lhs_end = outer_iterator == outer_end;
bool rhs_end = rhs.outer_iterator == rhs.outer_end;
if(lhs_end && rhs_end)
return true;
if(lhs_end != rhs_end)
return false;
return outer_iterator == rhs.outer_iterator
&& inner_iterator == rhs.inner_iterator;
}
private:
outer_range::iterator outer_iterator, outer_end;
inner_range::iterator inner_iterator, inner_end;
void update()
{
while(outer_iterator != outer_end)
{
inner_iterator = (*outer_iterator)->begin();
inner_end = (*outer_iterator)->end();
if(inner_iterator == inner_end)
++outer_iterator;
else
break;
}
}
};
Run Code Online (Sandbox Code Playgroud)
此类假定外部迭代器包含指向内部范围的指针,这是您的问题中的要求.这反映在update成员中,在箭头之前begin()和之前end().如果要在外部迭代器按值包含内部范围的更常见情况下使用此类,则可以用点替换这些箭头.注意BTW,这个类与内部范围包含指针的事实无关,只有类的客户端才需要知道.
如果我们使用代码可能会更短,boost::iterator_facade但没有必要为这么简单的事情添加一个boost依赖.此外,唯一棘手的部分是相等和增量操作,无论如何我们必须对它们进行编码.
我把以下的锅炉板成员留给了"为读者练习":
另一个有趣的练习是将其转换为适用于任意容器的模板.代码基本相同,只是你必须typename在几个地方添加注释.
使用示例:
int main()
{
outer_type outer;
int a = 0, b = 1, c = 2;
inner_type inner1, inner2;
inner1.push_back(&a);
inner1.push_back(&b);
inner2.push_back(&c);
outer.push_back(&inner1);
outer.push_back(&inner2);
my_iterator it(outer.begin(), outer.end());
e(outer.end(), outer.end());
for(; it != e; ++it)
std::cout << **it << "\n";
}
Run Code Online (Sandbox Code Playgroud)
哪个印刷品:
0 1 2
小智 7
迭代器只是一个支持某个接口的类.至少,您希望能够:
一旦你有一个可以为你的集合明智地做这个的类,你将需要修改集合以具有返回迭代器的函数.至少你会想要的