如何通过generate_n以索引增量填充STL容器

时间:2018-07-11 09:04:38

标签: c++ lambda stl

要使用依赖于它们的索引的值填充STL容器,我通常会像下面的代码那样编写。有什么方法可以不声明索引就做同样的事情?

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);});
}

4 个答案:

答案 0 :(得分:5)

您可以将索引移到lambda捕获中,并使lambda变得可变(需要C ++ 14):

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

现在,您可以省略行int idx = -1;。但是,可能有更好的解决方案,因为牺牲闭包的默认const限定条件只是将整数声明从周围的作用域移到捕获中并不完美。尽管如此,idx的范围已缩小,如果我正确理解您的问题,那就是目标。

答案 1 :(得分:3)

从性能上看,这看起来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;});
}

答案 2 :(得分:1)

如果您可以使用boost,则可以使用

#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);
}

答案 3 :(得分:1)

您可以在lambda函数中使用静态变量。如果列表很大,我认为这比每次在lambda中调用列表大小函数要好。

#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 << " ";
}