微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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的成员函数,但不一定需要正确的参数.

原文地址:https://www.jb51.cc/c/111160.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐