繁体   English   中英

C ++中反向迭代器的异常行为

[英]very weird behaviour of reverse iterator in C++

这是我今天在计算机上进行的一项测试,我被要求实施具有两个功能的Gardner类-每个都将标记割草的Gardner站立的一块土地,并将Gardner向左或向右移动3个单位。 如果Gardner的道路上有任何标有割草的土地,他将跳过该土地并继续前进到下一块。

我使用布尔变量向量对土地进行建模。 我正在将std :: find()与正向迭代器一起使用,以查找未在正确方向修剪的陆地,而我正在向左方向使用反向迭代器。 前向迭代器按预期工作。 但是,反向迭代器产生了一些奇怪的结果。 更具体地说,例如,在Visual Studio的调试器中,它显示反向迭代器指向的值为false(这是预期的),但是当我取消引用反向迭代器时,则为true。 可以在下面的代码中复制此代码,我已经附加了代码,对您的帮助将不胜感激。

#include <iostream>
#include <vector>
#include <algorithm>

class Gardener
{
public:
    Gardener(int n, int position)
        : mLands(n, false)
        , mPosition(position - 1)
    {
    }

    /**
    *   \brief Gardener has mowed the lawn at current house and moved left.
    *
    **/
    void mowAndMoveLeft()
    {
        mLands[mPosition] = true;
        //auto it = std::find(mHouses.rbegin() + mHouses.size() - mPosition + 1, mHouses.rend(), false);
        //it = std::find(it + 1, mHouses.rend(), false);
        //it = std::find(it + 1, mHouses.rend(), false);
        auto it = mLands.rbegin() + mLands.size() - mPosition + 1;
        int counter = 3;
        while (--counter >= 0)
        {
            while (it != mLands.rend())
            {
                if (*it == false)
                {
                    ++it;
                    break;
                }

                ++it;
            }
        }

        mPosition = mLands.rend() - it;
    }

    /**
    *   \brief Gardener has mowed the lawn at current house and moved right.
    *
    **/
    void mowAndMoveRight()
    {
        mLands[mPosition] = true;
        auto it = std::find(mLands.begin() + mPosition + 1, mLands.end(), false);
        it = std::find(it + 1, mLands.end(), false);
        it = std::find(it + 1, mLands.end(), false);
        mPosition = it - mLands.begin();
    }

    /**
    *   \return house number that gardener is mowing right now.
    *
    **/
    int whereAmI()
    {
        return mPosition + 1;
    }

private:
    std::vector<bool> mLands;
    std::size_t mPosition;
};

#ifndef RunTests
int main(int argc, const char* argv[])
{
    Gardener g(10, 2);
    std::cout << g.whereAmI() << '\n';

    g.mowAndMoveRight();
    std::cout << g.whereAmI() << '\n';

    g.mowAndMoveRight();
    std::cout << g.whereAmI() << '\n';

    g.mowAndMoveLeft();
    std::cout << g.whereAmI() << '\n';
}
#endif

要了解反向迭代器发生了什么,请在cppreference处查看reverse_iterator 更具体地说,看一下base()方法

基本迭代器引用的是下一个元素(从std::reverse_iterator::iterator_type角度而言),它是reverse_iterator当前指向的reverse_iterator 那是&*(rit.base() - 1) == &*rit

用英语:

*rit.base()反向迭代器的) *rit.base()将访问mLands的元素,该元素是*rit必须访问的元素之前的元素。 *rit*rit.base()之间的这种转换使得可以使mLands.rend()逻辑上指向mLands的第一个元素mLands 它是镜等效的mLands.end()指向过去的最后一个元素mLands

现在,了解您在调试器中看到的内容。 最有可能的,你的调试器展示你的价值rit.base()它指向一个元素早些时候在mLands ,比rit逻辑指向。 这可以解释您在此处看到的差异。 对于调试,如果不确定调试器将显示什么,则最安全的方法是打印*rit的值或将其存储在临时变量中,然后在调试器中进行检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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