C 的自定义迭代函数

Custom iterator function for c++

本文关键字:函数 迭代 自定义      更新时间:2023-10-16

我有一个我想迭代的" t"对象的集合。" T"类型的对象具有两个重要属性:

int r; // row number
int c; // column number 

我想定义一个迭代器,该迭代器允许我迭代集合的所有元素。

这可以使用:

完成
std::vector<T> v;
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    ....
}

但是,我希望迭代器再拥有一个属性。我希望能够打电话

it.nextrow()

调用此函数应返回v的元素" e",其中e.r 1 = ec.r和e.c = ec.c,其中ec是迭代器指向的当前元素。IE。nater it it.nextrow()应该给我一个指向列相同的元素的指针,但是行会增加一个。希望这是有道理的。

我不确定要做些什么才能使这项工作,因为我对高级C 概念是相当陌生的。有人可以帮我吗?

并非一切都必须是成员函数。您会接受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); });
}

如果您的矢量总是分类的,则不需要单独的开始,只需使用针头。

如果您确实需要它作为包装器迭代器的一部分,则该类型需要包含一个开始和结束。

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

迭代器可复制。

你可以

  • 源自容器的容器的迭代器,
  • 添加容器迭代器的结构,
  • 添加您的额外财产会员,
  • 并从您的自定义容器返回您的派生迭代器。

假设您的数据被包装在矢量中,连续的所有列的连续项目,然后是下一行的项目,您只需要*(iterator + column_count)即可访问下一个行 - 列值(请勿在已经指向最后一行数据的迭代器上尝试此功能)

您可以创建类似于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);
    }
};

用法示例:

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