[英]Custom iterator function for c++
I have a collection of object of type "T" that i want to iterate through. 我有一个要迭代的“ T”类型对象的集合。 An object of type "T" has two important properties:
类型“ T”的对象具有两个重要属性:
int r; // row number
int c; // column number
I would like to define an iterator that allows me to iterate through all elements of the collection. 我想定义一个迭代器,使我可以遍历集合的所有元素。
This can be done using: 可以使用以下方法完成:
std::vector<T> v;
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
....
}
However, I would like the iterator to have one more property. 但是,我希望迭代器具有更多的属性。 I would like to be able to call
我想打电话
it.nextrow()
calling this function should return the element "e" of v where er + 1 = ec.r and ec = ec.c, where ec is the current element pointed by the iterator. 调用此函数应返回v的元素“ e”,其中er + 1 = ec.r和ec = ec.c,其中ec是迭代器指向的当前元素。 Ie calling it.nextrow() should give me a pointer to the element where column is the same, but row is incremented by one.
即调用它。nextrow()应该给我一个指向元素的指针,其中column相同,但row递增1。 Hope it makes sense.
希望有道理。
I am not sure what I need to do in order for this to work, as I am fairly new to advanced c++ concepts. 我不确定要使它正常工作需要做什么,因为我对高级c ++概念还很陌生。 Can anybody help me?
有谁能够帮助我?
Not everything has to be a member function. 并非所有内容都必须是成员函数。 Would you accept a
iterator nextRow(iterator current, iterator begin, iterator end)
free function? 您是否接受
iterator nextRow(iterator current, iterator begin, iterator end)
免费功能?
template<typename Iterator>
Iterator nextRow(Iterator needle, Iterator begin, Iterator end)
{
return std::find_if(begin, end, [needle](const T & elem) { return (elem.r == needle->r + 1) && (elem.c == needle->c); });
}
If your vector is always sorted, you don't need a separate begin, just use needle. 如果向量总是被排序,则不需要单独的开始,只需使用needle即可。
If you do need this to be a part of a wrapper iterator, that type will need to contain a begin and end. 如果确实需要将其作为包装迭代器的一部分,则该类型将需要包含一个开始和结束。
template <typename Iterator>
class SearchableIterator
{
Iterator wrapped, begin, end;
public:
difference_type Iterator::difference_type;
value_type Iterator::value_type;
pointer Iterator::pointer;
reference Iterator::reference
iterator_category Iterator::iterator_category
SearchableIterator(Iterator wrapped, Iterator begin, Iterator end)
: wrapped(wrapped), begin(begin), end(end) {}
// All the members, calling that member of wrapped (see std::reverse_iterator for guidance)
SearchableIterator nextRow()
{
return SearchableIterator(std::find_if(begin, end, [this](const T & elem) { return (elem.r == wrapped->r + 1) && (elem.c == wrapped->c); }), begin, end);
}
}
Iterators are copyable. 迭代器是可复制的。
You can 您可以
Assuming your data are packed in a vector with consecutive items for all columns of a row followed by items of the next row, you would just need *(iterator + column_count)
to access the next-row-same-column value (don't try this on an iterator that's already pointing into the last row of data) 假设您的数据打包在一个向量中,该向量包含一行的所有列的连续项,然后是下一行的项,那么您只需要
*(iterator + column_count)
来访问下一行相同的列值(不在已经指向数据最后一行的迭代器上尝试此操作)
You can create a wrapper iterator similar to Implement custom iterator for c++ std container and give it a specific column count as additional information: 您可以创建类似于为c ++ std容器实现自定义迭代器的包装迭代器,并为其指定特定的列数作为附加信息:
template<typename T, int colsize, typename TIterator = std::vector<T>::iterator>
class MyRowIterator : public std::iterator<std::forward_iterator_tag, T>
{
private:
TIterator m_pter;
public:
MyRowIterator(TIterator& value): m_pter(value)
{
}
MyRowIterator(const MyRowIterator& other_it): m_pter(other_it.m_pter)
{
}
MyRowIterator& operator++()
{
++m_pter;
return *this;
}
bool operator!=(const MyRowIterator& rhs)
{
return m_pter != rhs.m_pter;
}
T& operator*()
{
return (*m_pter);
}
// here it is
T& nextrow()
{
return *(m_pter+colsize);
}
};
Usage example: 用法示例:
void Test()
{
std::vector<int> data;
// 2 rows each 10 columns
data.resize(20);
for (auto& item : data)
{
item = 0;
}
data[2] = 1;
data[12] = 5;
// don't iterate the last line, else nextrow() will access out of bounds!
for (MyRowIterator<int, 10> iter = data.begin(); iter != (data.end()-10); iter++)
{
std::cout << *iter << " # " << iter.nextrow() << std::endl;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.