c – std :: bind对我来说没有任何意义

下列:
#include <functional>

struct Foo 
{
    void bar1() {}
    void bar2(int) {}
    void bar3(int,int) {}
    void bar4(int,int,int) {}
};


int main()
{
    Foo foo;

    auto f1 = std::bind(&Foo::bar1,&foo);
    auto f2 = std::bind(&Foo::bar2,&foo);
    auto f3 = std::bind(&Foo::bar3,&foo);
    auto f4 = std::bind(&Foo::bar4,&foo);

    f1(1,2,3,4); // success
    f2(1,3);    // error
    f3(1,2);       // error
    f4(1);          // error    

    return 0;
}

f1(1,4)编译并执行bar1(). f2(1,3),不编译,f3(1,2)不编译(但bar3有正确的原型)和f4(1)不编译.对于这3种情况,Visual Studio 2013中出现的错误

“类没有将”operator()“或用户定义的转换运算符定义为需要适当数量的参数的”指向函数“或”引用到函数

我对模板和标准库的理解有限,但这对我来说似乎没有任何逻辑意义.有一个相当简单的解释吗?

解决方法

要将参数传递给目标,您需要在bind表达式中提供这些参数,或者通过向bind表达式添加占位符来保留它们的绑定,然后您必须调用带有参数的函数替换占位符.

你可以调用bar1没有占位符,因为它没有任何参数,所以你不需要传递任何东西.您传递给f1的参数只是被忽略,因为没有未绑定的参数,即没有占位符需要替换.

其他函数需要参数,因此您必须在“绑定时间”处绑定参数,例如.

auto f2a = std::bind(&Foo::bar2,&foo,1);
f2a();

或者保留参数未绑定,并在调用调用对象时提供它们:

auto f2b = std::bind(&Foo::bar2,std::placeholders::_1);
f2b(1);

请注意,GCC 5现在有静态断言来捕获这种错误.如果可以确定目标函数的arity,并且绑定表达式对目标函数的每个参数都没有绑定参数或占位符,那么它说:

/usr/local / gcc-head / include / c /5.0.0/functional:1426:7:错误:静态断言失败:指向成员的参数数量错误

你写的是相当于这个,使用lambdas而不是bind:

Foo foo;

auto f1 = [&foo](...) { return foo.bar1(); };
auto f2 = [&foo](...) { return foo.bar2(); };
auto f3 = [&foo](...) { return foo.bar3(); };
auto f4 = [&foo](...) { return foo.bar4(); };

f1(1,4); // success
f2(1,3);    // error
f3(1,2);       // error
f4(1);          // error

即定义要接受任何参数的函子,但忽略它们,然后调用Foo的成员函数,但不一定需要正确的参数.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...