将索引转换为迭代器

converting indexes to iterators

本文关键字:迭代器 转换 索引      更新时间:2023-10-16

我想用迭代器重新创建以下代码,只是为了学习。下面的代码检查 openFrameworks 中一个框的边界,基本上它会检查每当我的鼠标位置在 4 个矩形之一上时,它将一个布尔值变为 true,而将其他值变为 false。我最近非常喜欢迭代器,但由于某种原因,我无法使用迭代器来做到这一点,因为索引返回对象在向量中的位置,迭代器返回指向该位置的对象的指针。这是代码:

 for ( int i = 0; i < answersBox.size(); i++){
    for ( int j = 0; j < isHovered.size(); j++){
        if( x > answersBox[i].x && x < (answersBox[i].x + answersBox[i].width) && y > answersBox[i].y && y < (answersBox[i].y + answersBox[i].height)){
         if( i == j){
                isHovered[j] = true;
                cout << "This boolean number: " << j << " has become: " << isHovered[j] << endl;
            }else if( i != j){
                isHovered[j] = false;
            }
            }{
                cout << " These booleans number: " << j << " have become: " << isHovered[j] << endl;
        }
    }
}

谢谢!

您不应该盲目地将所有基于索引的循环转换为基于迭代器的循环。正如你所发现的,基于索引的循环有时可以更好(如:更易于阅读、编写、理解和维护(。

特别是以下一段代码:

if( i == j)

是一个很好的指标,表明基于索引的循环更适合此特定问题

如果您真的想尝试使用迭代器,请查看 std::distance .使用该函数,您可以将索引比较替换为:

if (std::distance(answersBox.begin(), iter1) == std::distance(isHovered.begin(), iter2)

顺便说一下,else if( i != j)没有意义,因为条件永远是真的。您可以将其替换为简单的else

我认为您无法使此代码在迭代器上运行,因为您无法比较指向不同容器的两个迭代器。

如果要将迭代器作为索引进行比较,可以编写

if(i-answersBox.begin()==j-isHovered.begin() )

这个呢?

typedef std::vector<std::pair<AnswerBox, bool> > answers_type;
answers_type answersBox;
for (answers_type::iterator i = answersBox.begin(); i != answersBox.end(); ++i)
{
  i->second = i->first->contains(x, y);
}

矢量存储两者的位置,答案框以及它是否悬停。

在这里,我使用了更面向对象的方法来定义

bool AnswerBox::contains(float x, float y) const
{
  return x > m_x && y > m_y && x < m_x + m_width && y < m_y + m_height;
}

其中 m_* 是答案框的成员变量(添加了前缀(。

PS 更好的是为 std::p air 使用自定义类。使事情经常更具可读性。即,具有元素包含AnswerBoxbool m_is_hoveredstd::vector<AnswerBoxHovered>。你会得到这样的代码:

i->set_is_hovered(x, y);

哪里

void AnswerBoXHovered::set_is_hovered(float x, float y)
{
  m_is_hovered = m_answer_box.contains(x, y);
}

等。