【问题标题】:Custom range-based iterator for a templated vector of vectors用于向量的模板化向量的自定义基于范围的迭代器
【发布时间】:2014-01-26 12:18:18
【问题描述】:

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

我们有一个 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> >();

};

【问题讨论】:

    标签: c++ 2d-vector


    【解决方案1】:

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

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

    请参阅this page 以了解for (var : collection) 语法实际转换为的内容。这告诉你需要设计一个迭代器类型Iter,它具有以下属性:

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

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

    其他说明:

    • 您的begin() 当前调用return iter(this, 0, 0);,它甚至无法编译。
    • 请不要像在vectorOfVectorsAddEmptyVector() 的声明中那样动态分配指向std::vector 的指针。首先,两者都不会编译,因为要编译它们,您需要将 vectorOfVectors 声明为 pointer to pointers to 向量的向量,而你不需要不想这样做,因为std::vector 在内部管理自己的动态内存分配——避免调用newdelete 是您首先使用std::vector 的主要原因。

    【讨论】:

    • 您是天赐良机,感谢您的建议。我会进一步调查。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2019-03-13
    • 2020-06-01
    • 2011-07-08
    相关资源
    最近更新 更多