no one special
no one special

Reputation: 1764

c++ repeat N iterations

I can clearly do something like this:

for(int i = 0; i < 10000; i++)
    testIteration();

But is there any std functions which does similar thing in one line? Something like that:

std::repeat(10000, testIteration);

Upvotes: 11

Views: 9589

Answers (6)

Dan H
Dan H

Reputation: 41

I know this isn't providing anything new from the above answers except that perhaps that my solution is very short. To repeat code 2 times I use a loop like the following:

for (auto _{2}; _--;) { /* this code gets repeated twice */ }

I think using the prefix operator would be less clear since to repeat code twice the loop would need to be:

for (auto _{3}; --_;) { /* this code gets repeated twice */ }

Parentheses would also of course work instead of braces, i.e.:

for (auto _(2); _--) {}

Upvotes: 1

no one special
no one special

Reputation: 1764

Just for a reference, there is std::generate and std::generate_n which can be used, but only for array initialization by doing something like this:

int i = 0;
std::generate_n(myArray, 10000, [&]() -> int { return i++; });

Upvotes: 0

theWiseBro
theWiseBro

Reputation: 1529

What about simply defining a macro? #define FOR(N, foo, ...) for (int _i = 0; _i < N; _i++) foo(__VA_ARGS__);

For eg.

#include <iostream>

#define FOR(N, foo, ...) for (int _i = 0; _i < N; _i++) foo(__VA_ARGS__);

void bar(int a, int b)
{
    std::cout << "hello " << a+b << std::endl;
}

int main()
{
    FOR(5, bar, 12, 6);
    return 0;
}

Output:

hello 18
hello 18
hello 18
hello 18
hello 18

Upvotes: -3

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123548

But is there any std functions which does similar thing in one line?

No, there is no algorithm in the standard library to do this (at least nothing that would not require to write useless boilerplate). As others already mentioned a loop is the most readable and least obfuscated way to do "something" n-times.

That being said, if you take it as an exercise to get a more terse syntax, you could write this:

#include <iostream>
struct my_counter {    
    int stop;
    struct iterator {
        int count;    
        iterator& operator++() { ++count; return *this; }
        int operator*() { return count;}
        bool operator!=(const iterator& other) { return count != other.count; }
    };
    iterator begin() { return {0}; }
    iterator end() { return {stop};}    
};

void print() { std::cout << "x"; }

int main() {
     for (auto x : my_counter{5}) print();
}

However, I would strongly advise against using something like that. Everybody knows how a loop works and what it does. Being used to for loops you can read a for loop in a blink, while anything else is uncommon, surprising and obfuscating, unless there is a standard algorithm of course (though I doubt that an algorithm for this particular case would be of great use). Why reinvent the wheel when you can use a loop?

Upvotes: 4

cigien
cigien

Reputation: 60440

I personally like to use a small helper function to do this.

template <typename F>
void repeat(size_t n, F f) {
  while (n--) f();
}

int main() {

   repeat(1000, [&] {
      testIteration();
   });
}

This avoids having to spell out the name of a variable. I prefer using view::iota when I need a name though.

That being said, I'm told this is confusing to read, and everyone can read a for loop, so that's probably the way to go. (Unless the function is put in std:: of course).

Upvotes: 5

Robert Andrzejuk
Robert Andrzejuk

Reputation: 5232

In the proposed standard for C++20 there is an example for iota_view:

for (int i : iota_view{1, 10})
  cout << i << ' '; // prints: 1 2 3 4 5 6 7 8 9

But for now, range-v3 library can be used:

for (int _ : view::iota{0, 10})
    testIteration();            // calls testIteration 10 times.

Upvotes: 12

Related Questions