转换const auto&到迭代器

时间:2016-05-31 23:58:49

标签: c++ c++11 iterator const auto

我最近阅读的一些帖子声称for(const auto &it : vec)与使用更长的迭代器语法for(std::vector<Type*>::const_iterator it = vec.begin(); it != vec.end(); it++)相同。但是,我发现this post说它们不一样。

目前,我正在尝试在使用后删除for循环中的元素,并想知道是否有任何方法可以将const auto &it : nodes转换为std::vector<txml::XMLElement*>::iterator

有问题的代码:

std::vector<txml2::XMLElement *> nodes;
//...
for (const auto &it : nodes)
{
    //...       
   nodes.erase(it);
}

我很确定我可以将std::vector<txml2::XMLElement*>重写为const指针,但不愿意,因为此代码仅用于调试。

2 个答案:

答案 0 :(得分:4)

您不应该尝试将范围中的范围声明转换为循环到迭代器,然后在迭代时删除它。即使在迭代时调整迭代器也是危险的,你应该依赖算法。

您应该使用Erase-remove idom 您可以将其与remove_if一起使用。

看起来像是:

  nodes.erase( std::remove_if(nodes.begin(), nodes.end(), [](auto it){

    //decide if the element should be deleted
    return true || false;

  }), nodes.end() );

目前在技术规范中,erase_if 这是上面显示的相同行为的更简洁版本:

std::erase_if(nodes,[](auto it){

    //decide if the element should be deleted
    return true || false;
});

答案 1 :(得分:1)

您没有得到迭代器,而是对元素的引用。除非你想用它做std::find,否则很难从中得到一个迭代器。

向量很好,所以你可以为每个元素增加一个计数器并执行nodes.begin() + counter来获取迭代器,但它有点打败了这一点。

同样删除for循环中的迭代器将导致你在向量结束后迭代,你可以测试这段代码:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {0,1,2,3,4,5,6};

    for (int x : v) {
        cout << x << endl;

        if (x == 2) {
            v.erase(v.begin() + 2);
        }
    }
    return 0;
}

如果你想使用迭代器,只需用它们循环,如果你想要删除一个中间循环,你必须遵循this answer

for (auto it = res.begin() ; it != res.end(); ) {
  const auto &value = *it;

  if (condition) {
    it = res.erase(it);
  } else {
    ++it;
  }
}

请注意,您不需要指定迭代器的整个类型,auto也可以。