我使用以下结构作为STL的generate_n
算法的输入:
struct GenerateNumber {
GenerateNumber () : i(0) {}
int operator () (void) {
return i++;
}
private:
int i;
};
使用此仿函数的代码示例如下:
std::vector <int> v1 (3);
std::vector <int> v2 (3);
GenerateNumber generateNumber;
std::generate_n (v1.begin (), 3, generateNumber);
std::generate_n (v2.begin (), 3, generateNumber);
但是,结果是v1
和v2
都包含{0,1,2}
,而不是v2
来包含{3,4,5}
。我已经通过断点验证了GenerateNumber
的构造函数只被调用一次(我知道构造函数被调用的次数没有多少,但无论如何都要检查它。)
我知道我可以通过使i
静态来解决这个问题,但我不明白这种行为。为什么在连续调用之间不保留i
的值?
答案 0 :(得分:8)
传递给generate_n
时会复制生成器对象。尝试使用std::ref
,即
std::generate_n(v1.begin(), 3, std::ref(generateNumber));
std::generate_n(v2.begin(), 3, std::ref(generateNumber));
编辑:请注意,std::ref
仅适用于C ++ 11。它在TR1中作为std::tr1::ref
引入,并且在boost boost::ref
中也可用。
答案 1 :(得分:3)
std::generate_n按值获取仿函数,也就是说,它会复制它。可能是您没有检查是否正在调用复制构造函数。
如果没有std::ref
,并且您的问题已在示例中进行了本地化,则可以修改您的仿函数,以便在对std::generate_n
的调用范围内引用计数器集:
struct GenerateNumber {
GenerateNumber (int& i) : struct GenerateNumber {
GenerateNumber () : i(0) {}
int operator () (void) {
return i++;
}
private:
int& i;
};
int main() {
int counter = 0;
std::vector <int> v1 (3);
std::vector <int> v2 (3);
GenerateNumber generateNumber(counter);
std::generate_n (v1.begin (), 3, generateNumber);
std::generate_n (v2.begin (), 3, generateNumber);
}