HiroIshida
HiroIshida

Reputation: 1603

How to fill STL containers by means of generate_n with index increment

To fill STL containers with values that depend on their index, I usually write like the code below. Is there any way to do the same without declaring the index?

int main(){
  static int N=10;
  auto func = [](int idx){return idx*(idx+1)+1;};
  int idx = -1;
  std::list<int> lst;
  std::generate_n(std::back_inserter(lst), N, [&](){idx++; return func(idx);});
}

Upvotes: 6

Views: 1178

Answers (4)

NeutronStar
NeutronStar

Reputation: 230

You can use static variable inside lambda function. I think it's better than calling list size function inside lambda everytime if your list size is big.

#include <iostream>
#include <algorithm>
#include <list>

int main()
{
   static int N = 10;
   std::list<int> lst;
   std::generate_n(std::back_inserter(lst),    
         N, [&](){
           static int idx = -1; 
           ++idx; 
           return idx*(idx+1)+1;
         });

   for(auto e : lst)
       std::cout << e << " ";
}

Upvotes: 1

YSC
YSC

Reputation: 40080

Performance wise, this looks equivalent:

#include <list>
#include <algorithm>

int main()
{
  std::list<int> lst;
  std::generate_n(std::back_inserter(lst), 10, [&](){auto idx = lst.size(); return idx*(idx+1)+1;});
}

Upvotes: 3

Caleth
Caleth

Reputation: 62864

If you can use boost, then this works

#include <algorithm>
#include <list>
#include <boost/iterator/counting_iterator.hpp>

int main()
{
    static int N = 10;
    std::list<int> lst;
    std::transform(boost::counting_iterator<int>(0), boost::counting_iterator<int>(N), std::back_inserter(lst), func);
}

Upvotes: 1

lubgr
lubgr

Reputation: 38287

You can move the index into the lambda capture and make the lambda mutable like this (requires C++14):

std::generate_n(std::back_inserter(lst), N,
    [&func, idx = -1] () mutable {idx++; return func(idx);});

Now you can omit the line int idx = -1;. There might be a better solution though, as sacrificing the default const qualification of the closure just to move an integer declaration from the surrounding scope into the capture isn't perfect. Still though, the scope of idx has been reduced, and if I understand your question correctly, this was the goal.

Upvotes: 7

Related Questions