基于范围的 for 循环是迭代一系列值的便捷语法。但是,它没有提供访问循环内当前对象索引的方法。如果您需要根据对象在容器中的位置对对象执行操作,这可能会出现问题。
幸运的是,有一种方法可以找到当前对象的索引,而无需维护单独的迭代器。诀窍是使用构图技术。我们可以使用索引来“压缩”它,而不是直接迭代容器。
它的工作原理如下:
拉链代码是一个创建新迭代器类型的类,该迭代器类型包装原始迭代器并添加索引字段。 iterator_extractor 结构用于从容器中提取底层迭代器类型。
template <typename T> class Indexer { public: class iterator { typedef typename iterator_extractor<T>::type inner_iterator; typedef typename std::iterator_traits<inner_iterator>::reference inner_reference; public: typedef std::pair<size_t, inner_reference> reference; iterator(inner_iterator it): _pos(0), _it(it) {} reference operator*() const { return reference(_pos, *_it); } iterator& operator++() { ++_pos; ++_it; return *this; } iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; } bool operator==(iterator const& it) const { return _it == it._it; } bool operator!=(iterator const& it) const { return !(*this == it); } private: size_t _pos; inner_iterator _it; }; Indexer(T& t): _container(t) {} iterator begin() const { return iterator(_container.begin()); } iterator end() const { return iterator(_container.end()); } private: T& _container; }; // class Indexer template <typename T> Indexer<T> index(T& t) { return Indexer<T>(t); }
要使用 Zipper 代码,只需将容器包装在索引器函数中并进行迭代在结果迭代器范围内。迭代器将提供当前对象的索引和值。
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto p: index(v)) { std::cout << p.first << ": " << p.second << "\n"; }
这将输出:
0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 6: 7 7: 8 8: 9
而拉链代码是一个强大的工具,用于在基于范围的 for 循环中查找当前对象的索引,还有一些替代方法可能更适合某些情况
单独的迭代器:维护单独的迭代器可以更直接地控制迭代过程。您可以使用迭代器显式查找当前对象的索引或对容器执行其他操作。
Boost.Range:Boost.Range 库提供了许多工具操作范围,包括索引适配器。索引适配器可用于创建一个迭代器范围,将原始范围中的每个元素与其索引配对。
自定义范围类:您可以创建自己的自定义范围类,它提供包含当前对象索引的迭代器。这种方法为您提供了控制迭代过程的最大灵活性。
有多个选项可用于在基于范围的 for 循环中查找当前对象的索引。您的应用程序的最佳选择将取决于具体要求和所涉及的权衡。
以上是如何在 C 基于范围的 For 循环中获取当前对象的索引?的详细内容。更多信息请关注PHP中文网其他相关文章!