使用基于范围的for循环时需要迭代器

目前,我只能做这个基于范围的循环:

for (auto& value : values) 

但有时我需要一个迭代器的值,而不是一个参考(无论出于何种原因)。 有没有办法通过比较值的整个向量?

使用旧的for循环:

 for (auto it = values.begin(); it != values.end(); ++it ) { auto & value = *it; //... } 

有了这个,你已经value it value 。 使用任何你想使用的。


编辑:

虽然我不会推荐这个,但是如果你想使用基于范围的循环(是的, 无论出于什么原因 :D),那么你可以这样做:

  auto it = std::begin(values); //std::begin is a free function in C++11 for (auto& value : values) { //Use value or it - whatever you need! //... it++; //at the end OR make sure you do this in each iteration } 

这种方法避免了search给定的value ,因为valueit总是同步的。

这是一个代理包装类,允许你通过将隐藏的迭代器别名到你自己的variables来公开隐藏的迭代器。

 #include <memory> #include <iterator> /* Only provides the bare minimum to support range-based for loops. Since the internal iterator of a range-based for is inaccessible, there is no point in more functionality here. */ template< typename iter > struct range_iterator_reference_wrapper : std::reference_wrapper< iter > { iter &operator++() { return ++ this->get(); } decltype( * std::declval< iter >() ) operator*() { return * this->get(); } range_iterator_reference_wrapper( iter &in ) : std::reference_wrapper< iter >( in ) {} friend bool operator!= ( range_iterator_reference_wrapper const &l, range_iterator_reference_wrapper const &r ) { return l.get() != r.get(); } }; namespace unpolluted { /* Cannot call unqualified free functions begin() and end() from within a class with members begin() and end() without this hack. */ template< typename u > auto b( u &c ) -> decltype( begin( c ) ) { return begin( c ); } template< typename u > auto e( u &c ) -> decltype( end( c ) ) { return end( c ); } } template< typename iter > struct range_proxy { range_proxy( iter &in_first, iter in_last ) : first( in_first ), last( in_last ) {} template< typename T > range_proxy( iter &out_first, T &in_container ) : first( out_first ), last( unpolluted::e( in_container ) ) { out_first = unpolluted::b( in_container ); } range_iterator_reference_wrapper< iter > begin() const { return first; } range_iterator_reference_wrapper< iter > end() { return last; } iter &first; iter last; }; template< typename iter > range_proxy< iter > visible_range( iter &in_first, iter in_last ) { return range_proxy< iter >( in_first, in_last ); } template< typename iter, typename container > range_proxy< iter > visible_range( iter &first, container &in_container ) { return range_proxy< iter >( first, in_container ); } 

用法:

 #include <vector> #include <iostream> std::vector< int > values{ 1, 3, 9 }; int main() { // Either provide one iterator to see it through the whole container... std::vector< int >::iterator i; for ( auto &value : visible_range( i, values ) ) std::cout << "# " << i - values.begin() << " = " << ++ value << '\n'; // ... or two iterators to see the first incremented up to the second. auto j = values.begin(), end = values.end(); for ( auto &value : visible_range( j, end ) ) std::cout << "# " << j - values.begin() << " = " << ++ value << '\n'; } 

我尝试了一下,发现了一个解决scheme。

用法:

 for(auto i : ForIterator(some_list)) { // i is the iterator, which was returned by some_list.begin() // might be useful for whatever reason } 

实施并不困难:

 template <typename T> struct Iterator { T& list; typedef decltype(list.begin()) I; struct InnerIterator { I i; InnerIterator(I i) : i(i) {} I operator * () { return i; } I operator ++ () { return ++i; } bool operator != (const InnerIterator& o) { return i != oi; } }; Iterator(T& list) : list(list) {} InnerIterator begin() { return InnerIterator(list.begin()); } InnerIterator end() { return InnerIterator(list.end()); } }; template <typename T> Iterator<T> ForIterator(T& list) { return Iterator<T>(list); } 

基于范围的循环被创build为java的foreach中的c ++对应,允许数组元素的简单迭代。 这是为了消除像迭代器这样的复杂结构的使用,以使其简单。 我想要一个iterator ,就像Nawaz说的那样,你将不得不使用正常for循环。

有一个非常简单的方法来做这个std::vector ,这也应该工作,如果你在这个过程中调整vector(我不确定接受的答案是否认为这种情况)

如果b是你的vector,你可以做

 for(auto &i:b){ auto iter = b.begin() + (&i-&*(b.begin())); } 

哪里将是你需要的迭代器。

这利用了C ++向量总是连续的事实。