在 C++11 中使用基于范围的 for 循环替换传统的嵌套循环

Using range based for loop to replace traditional nested loops in C++11

我正在尝试在我现有的一些代码中应用来自 C++11 std 的基于范围的 for 循环,这些代码有很多嵌套循环,如下所示:

vector<MyClass const*> myClassVec ; 
for(vector<MyClass const*>::const_iterator itr_m(myClassVec.begin()); itr_m != myClassVec.end(); ++itr_m) {
        const MyClass* star_m(*itr_m) ;
        <<<<Do something with star_m>>>>>
        for(vector<MyClass const*>::const_iterator itr_n(itr_m +1); itr_n != myClassVec.end(); ++itr_n) {
            const MyClass* star_n(*itr_n) ;
            if (star_m->GetIndex() == star_n->GetIndex()) {
                    <<Do something>>
            }
        }
}   

我想在这里使用自动变量和基于范围的for循环来简化我的代码。我很容易就能将这些应用到外循环,但我被卡住了 关于如何为内部循环执行此操作。基于范围的循环是否不适用于像内部 for 循环这样需要在容器的有限范围内循环的情况?

我为替换上面的嵌套循环代码而编写的代码,其中明显抛出内部 for 循环的编译错误:

vector<MyClass const*> myClassVec ; 
for(const auto& itr_m : myClassVec) {
    const MyClass* star_m(itr_m) ;
    <<<<Do something with star_m>>>>>   
    for(const auto& itr_n(itr_m +1);itr_n != myClassVec.end();++itr_n) {                
        const MyClass* star_n(*itr_n) ;
        if (star_m->GetIndex() == star_n->GetIndex()) {
            <<Do something>>
        }
    }
}

编译错误如下: error C2679: binary '!=' : 找不到接受 'std::_Vector_iterator<_Myvec>' 类型右手操作数的运算符(或没有可接受的转换)

有人可以阐明如何替换内部 for 循环,以及不打算使用基于范围的 for 循环的典型场景是什么。 提前致谢!

您的情况实际上无法使用基于范围的迭代的典型情况。只要您不关心 element/iterator 在容器中的位置,就可以使用它。相反,如果需要当前元素的索引(或指向它的迭代器),则需要经典循环。*

看你的例子:

for(const auto& itr_m : myClassVec)

这里,itr_m不是迭代器,而是对MyClass const*的引用,这意味着您丢失了有关元素位置的所有信息。

*您当然可以在 range-for 循环中跟踪当前元素,但这会破坏其目的并使代码更难阅读。

基于范围的 for 循环可能不是您在此处尝试执行的操作的最佳选择。基于范围的循环为您提供对对象的引用而不是迭代器。

然而,您可以使用自动语法简化它们以清理代码,如下所示:

vector<MyClass const*> myClassVec ; 
for(auto itr_m(myClassVec.cbegin()); itr_m != myClassVec.cend(); ++itr_m) {
  const MyClass* star_m(*itr_m) ;
  <<<<Do something with star_m>>>>>
  for(auto itr_n(itr_m +1); itr_n != myClassVec.cend(); ++itr_n) {
    const MyClass* star_n(*itr_n) ;
    if (star_m->GetIndex() == star_n->GetIndex()) {
      <<Do something>>
      }
    }
}   

技巧是使用 cbegin/cend 让自动获得你想要的 const_iterator。您还可以更进一步使用 auto 使代码更易于阅读,但这只是样式问题。

vector<MyClass const*> myClassVec ; 
for(auto itr_m(myClassVec.cbegin()); itr_m != myClassVec.cend(); ++itr_m) {
  auto star_m(*itr_m) ;
  <<<<Do something with star_m>>>>>
  for(auto itr_n(itr_m +1); itr_n != myClassVec.cend(); ++itr_n) {
    auto star_n(*itr_n) ;
    if (star_m->GetIndex() == star_n->GetIndex()) {
      <<Do something>>
      }
    }
}