I'm wondering: is there any possibility to add additional condition to for each? I'm thinking about something like:
int i=0; for(auto &it : list; i++) if(it.ID == 25) return i; or
for(auto &it : list, int i=0; i++) if(it.ID == 25) return i; Mandatory Reference: Sean Parent's "Seasoning C++" talk:
goal 1: Avoid raw loops
In cases like these, abstract your algorithm!
This will come up more often, so it's worth making it generic:
#include <algorithm> template <typename C, typename Pred> size_t index_if(C const& c, Pred&& pred) { const auto f(begin(c)), l(end(c)); auto match = std::find_if(f, l, std::forward<Pred>(pred)); return (l==match) ? -1 : std::distance(f, match); } Now you can write your query:
int main() { struct X { int ID; }; const std::vector<X> v { {1},{2},{3},{25},{4},{5},{6},{42} }; return index_if(v, [](X const& x) { return x.ID == 25; }); } See it Live on Coliru
PS. You might want a value-based version along with the predicate-based one:
template <typename C, typename V/* = typename C::value_type*/> size_t index_of(C const& c, V const v) { const auto f(begin(c)), l(end(c)); auto match = std::find(f, l, v); return (l==match) ? -1 : std::distance(f, match); }
boost::zip_iteratortogether with some sequence glue could do this for you. Something like:for( auto pair : zip(list, sequence(0, infinity)) ) { if( pair.first == 25) return pair.second; }syntax could be created with a bunch of work.