基于范围的自定义迭代器,用于矢量的模板化矢量

时间:2014-01-26 12:18:18

标签: c++ 2d-vector

我的任务一直让我疯狂。我一直在研究基本概念以增加我的知识,并尝试将其应用于这个问题,但我有点卡住了。

我们有一个main.cpp文件,用于测试具有以下语法的VectorOfVectors类:

for( int num : intVov )
{
     printf( "%d ", num );
}

我们正在创建我们自己的VectorOfVectors类,并将模板化矢量作为项目。

我们必须通过创建我们自己的自定义迭代器来使main函数正常工作,迭代遍历所有值,如main函数所示。我一直在研究基于范围的迭代器,但是我对如何构建自己的迭代器感到困惑,因为它是向量的向量,语法与一些在线示例不匹配。

我想指导我如何创建这个迭代器。我知道我需要一个begin()和end()函数,以及覆盖operator ++函数以使其工作。我的迭代器会使用int值作为我在operator ++中递增的指针吗?我需要两个指针吗? begin()和end()返回,迭代器或整数,或T值或向量是什么?我应该如何构造迭代器以及我需要哪些数据呢?迭代器构造函数会将两个指针作为值或一个,或者如何工作?迭代器是否需要自己的VectorOfVectors副本来迭代(并在构造函数中设置)?

我如何增加指针?任何帮助,一般知识甚至技巧都将不胜感激!

这是我一直在摆弄的东西,仅作为参考。

#include <vector>

using std::vector;


template< typename T > class VectorOfVectors
{
public:

    class iterator
    {
        public:
            //Constructor
            iterator(const VectorOfVectors<T> * vov, int pos_vov, int pos_v)
            {
                _pos_vov = pos_vov;
                _pos_v = pos_v;
                _vov = vov;
            }

            bool operator!= (const iterator & other) const
            {
                return pos != other._pos;
            }

            int operator* () const;

            const iterator operator++ ()
            {
                _pos_v++;
                if (_pos_v == _pos_vov->end())
                {
                    _pos_vov++;
                    if (_pos_vov == _vov.end())
                    {
                        --_pos_vov;
                        _pos_v = _pos_vov->end();
                        --_pos_v;
                        return (*this);
                    }
                    else
                    {
                        _pos_v = _pos_vov->begin();
                        return (*this);
                    }
                }
                else
                {
                    return (*this);
                }
            }

    private:
        int _pos_v;
        int _pos_vov;
        const VectorOfVectors<T> * _vov;
    };

    void AddEmptyVector()
    {
        vectorOfVectors.push_back(new vector<T>());
    }

    int GetVectorCount() const
    {
        return vectorOfVectors.size();
    }

    vector<T> GetVectorAtIndex(int index)
    {
        return vectorOfVectors.at(index);
    }

    void AddCopyOfVector(vector<T> & toBeAdded)
    {
        vectorOfVectors.push_back(toBeAdded);
    }

    iterator begin() const
    {
        return iter(this, 0, 0);
    }

    iterator end() const
    {
        return iterator(this, 4, 3);
    }

private:
    vector< vector<T> > vectorOfVectors = new vector< vector<T> >();

};

1 个答案:

答案 0 :(得分:0)

从您发布的for循环看来,教师似乎希望迭代器迭代向量矢量的各个元素(而不是例如,通过子向量)。 / p>

begin()end()必须始终返回迭代器,而不是迭代器指向的元素(例如,在这种情况下不是原始int)。在某些特殊情况下,可能会生成这些原始指针(例如,我认为std::vector::iterator的某些STL实现会执行此操作),但通常它们需要包含足够信息才能导航的小struct父数据结构。

有关for (var : collection)语法实际转化为什么的详细说明,请参阅this page。这告诉您需要设计具有以下属性的迭代器类型Iter

  • *Iter会返回T或可转换为T的内容(例如T&)。您目前有错误 - 由于某种原因,您的int operator* () const;(似乎没有定义?)正在返回int
  • ++Iter将迭代器移动到下一个元素。
  • 当两个迭代器指向同一个元素时,
  • Iter1 != Iter2返回false

您实际创建Iter类型的方式完全取决于您。正如你现在所做的那样,使用2个整数索引并检查++上的“环绕”对我来说似乎是合理的。

其他说明:

  • 您的begin()当前正在调用return iter(this, 0, 0);,甚至无法编译。
  • 请不要像std::vector声明和vectorOfVectors中那样动态分配指向AddEmptyVector()的指针。首先,它们都不会编译,因为要编译它们,你需要将vectorOfVectors声明为指向 指向向量的向量的指针,然后你不希望这样做,因为std::vector在内部管理自己的动态内存分配 - 避免必须调用newdelete是您使用std::vector的主要原因首先。