2012-08-31 93 views
2
#include <functional> 
#include <iostream> 

struct Test 
{ 
    void fnc(int & a) { ++a; } 
}; 

int main() 
{ 
    typedef std::function<void(int)> Func; 

    int i = 0; 
    Test t; 
    Func f = std::bind(&Test::fnc, &t, std::ref(i)); 
    //f(); //error C2064: term does not evaluate to a function taking 0 arguments 
    f(37); //Here I am forced to pass evidently unused int 
    std::cout << i; 
} 

我是否正确地使用它?调用std :: bind(ed)和std :: ref参数的函数

真的有必要通过一些随机int吗?

如果是这样,为什么呢? 是因为模板的魔力是有限的,而且我实际上必须将int传递给int函数,或者是为了某些目的而设计的? (例如,强制用户不在于怎么忘记了函数的声明已经样子?)

我用vs2012

回答

5

不,不,不,你有什么是采取参数的函数,因为一切都是绑定已经!你想以下两种方法之一:

std::function<void()> f = std::bind(&Test::fnc, &t, std::ref(i)); 

std::function<void(int&)> g = std::bind(&Test::fnc, &t, std::placeholders::_1); 

现在以下两个效果t.fnc(i)

f(); // OK, bound to `i` always. 

g(i); // Same effect 

注意,如果可能,你应该声明的约束功能为auto,这是更有效的。第三个选项是关闭表达式[&i,&t](){t.fnc(i);}

+0

谢谢你,Kerrek – relaxxx

+0

有一个问题,是否可以通过ref传递,但在调用期间提供变量,而不是在绑定期间?或者,如果我不想复制整个对象(int这里是错误的例子)我使用占位符,但与指针? – relaxxx

+0

@relaxxx:“g”不符合这些要求吗? (请注意我刚才所做的修正;现在需要一个*参考*) –

1

有两个地方需要查看参数:在调用bind()时,参数成为绑定对象的一部分,并且在调用绑定对象本身时,参数被传递给占位符是在原来的电话bind()中建立的。在这里的示例中,在调用bind()时没有占位符,因此在调用绑定对象时不需要任何参数。如果你用比它需要更多的参数来调用它,多余的会被忽略。

此处的代码通过将其包装到一个std::function对象中来为绑定对象添加一个图层。为std::function对象(此处为std::function<void(int)>)定义的签名确定如何调用该对象:它采用类型为int的参数,并将该值传递给绑定对象,该对象会忽略它。