On 7/2/2018 9:29 PM, jacobnavia wrote:
> Le 01/07/2018 à 23:40, Vir Campestris a écrit :
>> Use the old syntax. Then you can type i +=2 to skip the alternate ones.
>
> Why is the index not included as info with the new syntax?
>
> Yes, you can figure it out, as several people pointed me to a simple
> solution, so its not a big deal.
Since you are calling the range-for the "new syntax", maybe it is worth
recalling that the "range-based for" statement (as the standard defines
it) it is an /alternative/ formulation of the for loop additional to the
for(init; condition; update){ } one, and not meant to be a replacement
or obsolete the traditional syntax.
From this perspective, it is /intentional/ that the loop variable is
not present in the range-for expression: the intent is that given a
collection, some block of instructions is executed on each element of
the collection - hence the syntax only involving the collection and a
declaration of the element to be acted upon during each iteration.
Moreover, the syntax itself only allows for iteration over /all/
elements in the collection, and not even the ordering of the traversal
is explicit in the expression - it is written in the standard that it
runs from begin() to end(), not in the coding.
So, as other have said, if the loop variable is actually instrumental to
processing in the loop, then probably the traditional syntax is a better
choice.
Out of curiosity, below are a few alternatives, the last one being the
suggestion from Alf, with the addition of an index filter:
=================================
#include <iostream>
#include <vector>
#include <boost/range/adaptor/indexed.hpp>
#include <boost/range/adaptor/filtered.hpp>
template< typename Range >
auto enumerate( const Range& r ) { return boost::adaptors::index( r ); }
template< typename Range >
bool is_even(const typename boost::range_value<Range>::type& x) { return
x.index()%2 == 0; }
template< class Type >
auto filter_even( const Type& c ) { return boost::adaptors::filter( c,
is_even<Type> ); }
int main()
{
std::vector<wchar_t> values{ L'a', L'b', L'c', L'd', L'e' };
// your original
for (int i=0; i<values.size(); ++i)
{
if (i&1) continue;
std::wcout << values[i] << std::endl;
}
std::wcout << std::endl;
// minimal loop, avoiding anything like __begin, __end ...
for (const auto& c: values)
{
if ((&c - &(values[0])) & 1 ) continue;
std::wcout << c << std::endl;
}
std::wcout << std::endl;
{
// explicit iterator, with a flag
bool skip = false;
for (auto it = values.cbegin(); it != values.cend(); ++it)
{
if (!(skip = !skip)) continue;
std::wcout << (*it) << std::endl;
}
}
std::wcout << std::endl;
// the example from Alf, with a filtered index
for( const auto& item : filter_even( enumerate( values ) ) )
{
std::wcout << item.index() << ": " << item.value() << std::endl;
}
}
=================================
>
> Of course you can do i += 2, but I ws thinking in terms of a filter
> going through all records according to some criteria. An easy criteria
> was using the index, but that was a very bad example.
See above for a boost filter
>
> Thanks
>