C ++迭代迭代器

时间:2015-08-23 11:19:08

标签: c++ c++11 vector stl

我目前正在"现代化"我的玩具编译器代码使用尽可能多的C ++ 11功能来学习如何编写现代C ++。在查看我的代码,搜索现代化的东西时,我发现了这个构造:

for (size_t i = 0; i < _vector.size(); i++) {
   for (size_t j = 0; j < _vector[i].length(); j++) {

_vector是一个std::vector<std::string>,包含需要编译的文件的源代码。向量中的每个std::string都是需要编译的一行代码。在编译之前,编译器会检查要编译的代码是否有任何语法错误,此检查的第一步是查找缺少的分号。我这样做是通过逐个查看每个字符并检查所述字符是否是分号。如果是,我通过构建一种迷你语法树来检查是否需要分号,从而确定是否有必要。我目前使用_vector[i][j]访问每个字符,这非常让人想起ANSI-C(这是你访问char *数组中每个字符的方式),我想用迭代器替换它。据我所知,Iterator是一个类似指针的构造,它指向容器/序列/中的元素。应用指针类比我推断出std::vector<std::string>::iterator指向向量中的字符串,因此理论std::vector<std::string>::iterator::iterator将指向字符串对象中的单个字符。但是因为在STL中没有这样的东西,指针类比在这里没有多大用处。所以我的问题是:如何访问std::vector<std::string>::iterator中的每个角色?

2 个答案:

答案 0 :(得分:5)

如果您可以访问完整的C ++ 11支持,为什么还要使用显式迭代器类型呢?这就是auto的来源:

std::vector<std::string> sv;
//fill vector...

for(const auto& s : sv)
{
    for(const auto& c : s)
    {
        //'c' represents current character
    }
}

我们在这里使用range-base for loop。在第一个循环中,s是一个const引用 (*) 到来自vector的当前字符串。由于std::string支持迭代语义,我们也可以使用for迭代它。 c是对字符串(s)中当前字符的const引用。

现场演示: click

(*) 由于您的循环似乎是只读的,因此应使用const引用。如果您要执行任何修改,只需将其从const auto&更改为auto&

答案 1 :(得分:2)

iterator的行为类似于指针。因此,在您的情况下,您可以取消引用第一个迭代器以获取string并使用std::string::iterator来访问每个字符。

另一种方法是使用operator->()直接获取std::string::iterator,例如

for (std::vector<std::string>::iterator i = _vector.begin(); i != _vector.end(); ++i) {
    for (std::string::iterator j = i->begin(); j != i->end(); ++j) {
        /* ... */
    }
}

使用C ++ 11,您可以将其简化为

for (auto i = _vector.begin(); i != _vector.end(); ++i) {
    for (auto j = i->begin(); j != i->end(); ++j) {
        /* ... */
    }
}

正如@LightnessRacesinOrbit提到并且@MateuszGrzejek已经显示,下一步将转移到Range-based for loop。从第一个begin()到最后一个end()元素迭代的循环

for (auto i = _vector.begin(); i != _vector.end(); ++i) {
    // Do something with string (*i)

可以写成

for (auto &s : _vector) {
    // Do something with string (s)

或者,如果您不修改字符串,请将其设为const

for (const auto &s : _vector) {
    // Do something with string (s)