Iterating over an odd (even) elements only in a range-based loop

前端 未结 4 1289
无人共我
无人共我 2021-02-15 16:23

Suppose we have a plain array (or other container which support range based loops):

const int N = 8;
int arr[N] = {0, 1, 2, 3, 4, 5, 6, 7};

Usi

4条回答
  •  春和景丽
    2021-02-15 17:11

    As for what you are currently asking; I do not believe anything exists yet. Now as for iterating over a container by some integer N we can do the following; we can write our own for_each type of function. I've written one below and it works like a gem! You may also want to look into the std::advance function as well for it can be another possible implementation. I was checking that out myself as I was writing this function. However; as for c arrays I'm not sure there is much one can do without a bunch of extra code such as class templates, wrappers, etc. Here is my function.

    #include 
    #include 
    #include 
    
    template
    void for_each_by_n( Container&& 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 < increment_by; ++n ) {
                if ( it == end_it ) return;
                ++it;
            }
        }
    }
    
    int main() {
        std::array arr{ 0,1,2,3,4,5,6,7 };
        std::vector vec{ 1.2, 1.5, 1.9, 2.5, 3.3, 3.7, 4.2, 4.8 };
    
        auto l = [](auto& v) { std::cout << v << ' '; };
    
        for_each_by_n(arr, l); std::cout << '\n';
        for_each_by_n(vec, l); std::cout << '\n';
    
        for_each_by_n(arr, l, 2); std::cout << '\n';
        for_each_by_n(arr, l, 4); std::cout << '\n';
    
        for_each_by_n(vec, l, 3); std::cout << '\n';
        for_each_by_n(vec, l, 5); std::cout << '\n';
    
        for_each_by_n(arr, l, 8); std::cout << '\n';
        for_each_by_n(vec, l, 8); std::cout << '\n';
    
        // sanity check to see if it doesn't go past end.
        for_each_by_n(arr, l, 9); std::cout << '\n';
        for_each_by_n(vec, l, 9); std::cout << '\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
    

    What I like about this example above is that not only can you increment through a loop by some integer N; the above function also takes a function pointer, function object, functor, or lambda and it will perform the required action.

    In your case you was trying to loop through your container by 2 for ever odd or every even index and within the loop you were printing the results. Here in my example; I'm printing the results in the form of a lambda that is being passed to this function.

    However the only caveat with this particular implementation is that it will always start from index 0. You could easily expand on this by introducing another integer parameter as to an offset of where the iteration will begin; but I'll leave that up to you to do as an exercise.

    For the time being we have to settle for what C++11 through C++17 has to offer. In the near future we should have many new and powerful features with the release of C++20.

提交回复
热议问题