使用reference。 std :: generate的行为应该等同于:
template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
while (first != last) {
*first = gen();
++first;
}
}
但是当我尝试用0-99数字填充矩阵时。相反,我得到10行0-9。那是为什么?
std::vector< std::vector<int> > m;
#ifdef GENERATE
struct Generator{
int seq;
Generator():seq(0){};
int operator()(){return seq++;};
} generator;
#elif defined FOR_EACH
int i = 0;
auto increment = [&i](int &a){a = i++;};
#endif
int x = 10, y = 10;
m.resize(x);
for(auto &v : m)
{
v.resize(y);
#ifdef GENERATE
generate(begin(v), end(v), generator);
#elif defined FOR_EACH
for_each(begin(v),end(v), increment);
#endif
}
答案 0 :(得分:3)
您也可以使用std::ref来防止复制Generator对象:
generate(begin(v), end(v), std::ref(generator));
答案 1 :(得分:2)
因为您的生成器是根据签名
复制的void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
copied ----^^^^^^^^^^^^^
即。你保留自己的副本,std::generate
也可以。每当您将自己的,未经修改的generator
传递给std::generate
时,即每次开始使用具有其计数器0
的版本时。
您需要以某种方式保留您的仿函数中的计数器并在Generator
的使用中共享它,例如
struct Generator{
int *seq;
Generator(int &seq):seq(&seq){};
int operator()(){return (*seq)++;};
};
....
int seq = 0;
generate(begin(v), end(v), Generator(seq));
或等效
int seq = 0;
generate(begin(v), end(v), [&seq]() { return seq++; });
答案 2 :(得分:2)
如果是std::for_each
的情况,则传递lambda函数increment
,它通过引用获取自动变量int i = 0;
。对于每次调用for_each
,它都会创建一个新的increment
仿函数,但i
不会重置,只会递增;因此,您会看到值是连续的。 lambda函数(i
)的内存在其自己的域之外,即在父函数main中。
如果您拥有自己的generate
功能,则资源位于结构内,即重新初始化Generator::seq
。对于generate
的每次调用,都会创建一个新的Generator;它的构造函数将seq
初始化为0,每次都重置计数。
#ifdef GENERATE
int i = 0; // lives in main
struct Generator {
int &seq;
Generator(int &i):seq(i) { }
int operator()() { return seq++; }
} generator(i);
#else
这应该有效,因为Generator的内存部分现在处于更高的水平。