简体   繁体   English

C ++的自定义迭代器函数

[英]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 您可以

  • derive from the container's iterator for your container, 从容器的容器迭代器派生,
  • add construction from the container's iterator, 从容器的迭代器添加构造,
  • add your extra property members, 添加您的额外财产成员,
  • and declare that begin(), end(), etc from your custom container return your derived iterator. 并声明自定义容器中的begin(),end()等返回派生的迭代器。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM