代码之家  ›  专栏  ›  技术社区  ›  HiroIshida

如何利用索引增量生成STL容器

  •  4
  • HiroIshida  · 技术社区  · 7 年前

    为了用依赖于其索引的值填充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 回复  |  直到 7 年前
        1
  •  5
  •   lubgr    7 年前

    您可以将索引移动到lambda捕获,并使lambda像这样可变(需要C++ 14):

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

    现在你可以省略这行了 int idx = -1; . 不过,可能有更好的解决方案,因为牺牲闭包的默认常量限定,只是为了将整数声明从周围的范围移动到捕获中,这并不完美。尽管如此, idx 已经减少了,如果我正确理解你的问题,这就是目标。

        2
  •  3
  •   YSC    7 年前

    性能方面,这看起来 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;});
    }
    
        3
  •  1
  •   Caleth    7 年前

    如果你能用的话 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);
    }
    
        4
  •  1
  •   NeutronStar    7 年前

    您可以在lambda函数内使用静态变量。我认为,如果列表大小很大,那么每次调用lambda内部的list-size函数都要好。

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