如何用索引增量generate_n填充STL容器

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

本文关键字:填充 STL 容器 generate 何用 索引      更新时间:2023-10-16

要用依赖于其索引的值填充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);});
}

您可以将索引移动到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的范围已经缩小,如果我正确理解你的问题,这就是目标。

性能方面,这看起来相当于:

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

如果你可以使用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);
}

您可以在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 << " ";
}