通过引用传递仿函数,我在VS2012上运行它,为什么会出错?

时间:2016-03-31 07:01:42

标签: c++ visual-studio-2012 stl

这是我的代码: 结果应该是1,2,3,4,5,6,但它仍然是1,2,3,1,2,3。当我在linux上运行它时,它是正确的。谁能告诉我真相。

class IntSequence {
private:
    int value;
public:
    IntSequence(int initialValue) : value(initialValue){}
    int operator() () {
        return value++;
    }
};
int main()
{

    list<int> coll;
    IntSequence seq(1);
    generate_n<back_insert_iterator<list<int> > , int , IntSequence& >
         (back_inserter(coll) , 3 ,seq);//result is 1,2,3
    generate_n (back_inserter(coll) , 3 ,seq);//result should be 1,2,3,4,5,6,but it is still 1,2,3,1,2,3
 }

1 个答案:

答案 0 :(得分:3)

使用std::ref,否则generate_n会创建一个新的IntSequence仿函数,增加它的值,然后销毁它。

http://ideone.com/pBHum1

list<int> coll;
IntSequence seq(1);

generate_n (back_inserter(coll), 3, std::ref(seq));
generate_n (back_inserter(coll), 3, std::ref(seq));

for (auto& i : coll)
   cout << i << " ";

解释为什么它在visual studio中不起作用:

在VS2015(以及2012年的情况下)中,generate_n会调用一个内部私有函数_generate_n,它根本不接受转发引用或引用。相反,它再次接受_Fn值。

因此,即使您通过显式设置模板参数实际上正确地传递了引用,它也会随后调用_generate_n

我不知道这是否意味着这样。但可能是这样,因为这就是为什么std::reference_wrapper首先存在的原因。