My implementation of a for_each function that traverses a std::container by some step size integer N As my answer to Iterating over an odd (even) elements only in a range-based loop, I wrote this function, with the following driver program and output:

#include &lt;array&gt;
#include &lt;vector&gt;
#include &lt;iterator&gt;

// Forward iteration from begin to end by step size N.
template&lt;typename Container, typename Function&gt;
void for_each_by_n( Container&amp;&amp; cont, Function f, unsigned increment_by = 1) {
    if ( increment_by == 0 ) return; // must check this for no op

    using std::begin;
    auto it = begin(cont);

    using std::end;
    auto end_it = end(cont);

    while( it != end_it ) {
        f(*it);
        for ( unsigned n = 0; n &lt; increment_by; ++n ) {
            if ( it == end_it ) return;
            ++it;
        }
    }
}

int main() {
    std::array&lt;int,8&gt; arr{ 0,1,2,3,4,5,6,7 };
    std::vector&lt;double&gt; vec{ 1.2, 1.5, 1.9, 2.5, 3.3, 3.7, 4.2, 4.8 };

    auto l = [](auto&amp; v) { std::cout &lt;&lt; v &lt;&lt; ' '; };

    for_each_by_n(arr, l); std::cout &lt;&lt; '\n';
    for_each_by_n(vec, l); std::cout &lt;&lt; '\n';

    for_each_by_n(arr, l, 2); std::cout &lt;&lt; '\n';
    for_each_by_n(arr, l, 4); std::cout &lt;&lt; '\n';

    for_each_by_n(vec, l, 3); std::cout &lt;&lt; '\n';
    for_each_by_n(vec, l, 5); std::cout &lt;&lt; '\n';

    for_each_by_n(arr, l, 8); std::cout &lt;&lt; '\n';
    for_each_by_n(vec, l, 8); std::cout &lt;&lt; '\n';

    // sanity check to see if it doesn't go past end.
    for_each_by_n(arr, l, 9); std::cout &lt;&lt; '\n';
    for_each_by_n(vec, l, 9); std::cout &lt;&lt; '\n';

    return 0;
}


Output

 0 1 2 3 4 5 6 7
 1.2 1.5 1.9 2.5 3.3 3.7 4.2 4.8
 0 2 4 6 
 0 4
 1.2 2.5 4.2
 1.2 3.7
 0
 1.2
 0
 1.2


I did my best to check for possible bugs, corner cases etc.

What I would like to know about my function above:


Does this follow modern C++ standards?
Is there any room for improvements?
Did I miss any possible bugs that I might have overlooked?
Would this be considered readable, reliable, generic, portable, cross-platform and reusable?
Do I have to worry about any const correctness, type deduction, cache misses and the like?
-Note-: I know the above function is not in a designated namespace; that is not of concern here. I can do that without hassle or trouble. 


Let me know what you think; I'm looking forward to any and all feedback.

I would like to know ahead of time for I am thinking about adding a second unsigned integer parameter to this function. It would allow the user to choose the index location they want to use for their starting position. This parameter would default to 0.
We could use Container::size_type or std::size_t for the increment_by parameter, or (as standard algorithms like std::for_each_n seem to do) make it a template argument and use the same type while incrementing n.
The standard library algorithms take iterators rather than containers. You mention allowing users to specify an "index location they want to use for their starting position", which would be accomplished by passing an iterator range instead of calling begin and end.
I don't think the default increment_by argument value is useful. If we needed a step size of 1, we'd call std::for_each or use a range-based for loop.
std::for_each returns the function object (which can be helpful for something like summing values). We could do the same.
Follow the standard library conventions with naming template arguments (e.g. name the minimum required iterator type, make it clear that the function is a unary function).




Modified version:

template&lt;class InputIt, class Size, class UnaryFunction&gt;
UnaryFunction for_each_by_n(InputIt begin, InputIt end, Size step, UnaryFunction f) {

    if (step == 0)
        return f;

    while (begin != end)
    {
        f(*begin);

        for (Size n = 0; n != step; ++n)
        {
            if (begin == end)
                return f;

            ++begin;
        }
    }

    return f;
}


(edit: removed unnecessary std::move per Juho's comment).