使用基于范围的 for 循环遍历自定义容器

Custom container traversal with range-based for loop

在C++中,一些STL容器如vector、map、string可以通过带冒号的for循环遍历。

例如:

for(auto c:v)

写自定义容器的时候,能不能像Java那样遍历(只需要实现Iterable)?

是的,您需要实现某种形式的迭代器并覆盖 std::begin(container) 和 std::end(container)(如果您的容器具有 begin 和 end 方法,也可能有效)。

在内部,代码等同于以下内容(这只是为了说明问题,编译器的编写方式可能略有不同,有关详细信息,请参阅 here)。

auto _end = end(v);
for (auto _it = begin(v); _it != _end; ++_it) {  
    auto c = *_it;
    <the rest of loop code>
}

因此,如果您的迭代器和覆盖按预期工作,它也适用于 for 循环。

您可以有以下简单的等同于 Java Iterable 接口:

template <typename T, typename U>
struct iterable {
    T _begin;
    U _end;

    iterable(T begin, U end)
        : _begin(begin),
          _end(end)
    {}

    T begin() {
        return _begin;
    }

    U end() {
        return _end;
    }
};

如果你想知道为什么开始迭代器和结束迭代器应该相同时会有 TU。原因是有些容器没有这两个相同类型的迭代器。

此外,您可以实现辅助函数 make_iterable,例如:

template <typename T, typename U>
iterable<T, U> make_iterable(T t, U u) {
    return iterable<T,U>(t, u);
}