【问题标题】:iterate through two std::lists simultaneously同时遍历两个 std::lists
【发布时间】:2013-11-12 15:44:07
【问题描述】:

抱歉,这个问题太简单了。

之前的错误检查确保l1.size() == l2.size()

std::list<object1>::iterator it1 = l1.begin();
std::list<object2>::iterator it2 = l2.begin();

while(it1 != l1.end() && it2 != l2.end()){

  //run some code

  it1++;
  it2++;
}

这是一种合理的方法,还是有更优雅的解决方案?感谢您的帮助。

【问题讨论】:

  • 次要点:递增迭代器的常用习语使用前缀而不是后缀++。 IE。 ++它1;而不是 it1++;这与性能相关的原因不明。
  • 还有一个小问题:如果 l1.size() == l2.size() 你只需要在 while 条件下进行一次测试。
  • @DaleWilson:这并不是那么晦涩难懂。这只是后增量运算符所需的复杂(不是数学意义上的)类型所产生的复制构造开销。
  • @TomSwifty:这真的取决于你要增加什么。 operator++() 应该返回 T&amp;,而 operator++(int) 返回 T。但是,考虑到返回值优化、移动语义等等,我不确定它是否真的会给当今的编译器带来问题。
  • 它用于给定对象类型的迭代器。原因是后增量会创建一个副本,对其进行增量,然后返回原始值。贵的是副本。

标签: c++ iterator std


【解决方案1】:

如果无条件发生增量,我更喜欢使用for

for(; it1 != l1.end() && it2 != l2.end(); ++it1, ++it2)
{
    //run some code
}

您可以在列表大小相同的情况下省略一项测试,但我不确定运行一些代码中发生了什么!

【讨论】:

  • 你也可以在 for 循环头中包含 init 吗? for(iterator it1 = l1.begin(), iterator it2 = l2.begin() ... ?
  • 是的,有可能
【解决方案2】:

我认为这是完全合理的(除了我会使用前置增量而不是后置增量)。

您可以考虑使用某种"zip iterator",但在这种情况下,这并不完全值得麻烦。

【讨论】:

    【解决方案3】:

    如果你对每一对对象做一个简单的操作,你可以使用std::transform

    【讨论】:

      【解决方案4】:

      按照您的方式进行操作是合理的,您可以采取其他一些方法来最大限度地减少检查的数量:

      如果您已经检查了两个长度是否相等(如先前检查所述),则标准 for 循环可能就足够了,它消除了对两个变量的访问,并且仅依赖于一个变量的增量:

      for (int i = 0; i< l1.size();i++)
      {
          // run some code here
      }
      

      但是,您需要使用advance()next() 在“此处的一些代码”中遍历列表中的对象。

      【讨论】:

        猜你喜欢
        • 2018-12-10
        • 1970-01-01
        • 2021-12-30
        • 2011-02-12
        • 1970-01-01
        • 2011-08-03
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多