【问题标题】:How to std::bind a class function properly?如何正确 std::bind 类函数?
【发布时间】:2014-12-16 21:55:23
【问题描述】:
class A
{
public:
    A();
    void Func1(int,int);
    void Func2(long,long);
private:
    ...
};

<implementation here>

主要:

std::vector<std::function<void(void)>> fl;
A a;
fl.push_back(std::bind(&a.Func1, 1,1));

给出错误: ISO C++ 禁止使用绑定成员函数的地址来形成指向成员函数的指针

解决方案?

编辑:更改“A a();”到“A a;”。这里没有构造函数:P

编辑: 选择Praetorian的回复作为答案,因为它解决了问题。 Dietmar Kühl's 也是一个很好的解决方案,但不是问题的实际答案。 必须公平:D

【问题讨论】:

    标签: c++ class object callback


    【解决方案1】:

    Func1 是一个非静态成员函数,因此必须在A 的实例上调用它,您需要将bind 作为第一个参数(this 指针)。另外,在创建指向成员函数的指针时,语法为&amp;ClassName::MemFuncName

    所以你需要

    fl.push_back(std::bind(&A::Func1, &a, 1, 1));
    

    确保a 的生命周期在调用绑定函数之前没有结束。

    【讨论】:

    • 好的,如果我有 A a;乙;一个 c;广告;并且想要绑定所有这些,正确的方法是使用您上面写的行,但是将“&a”更改为“&b”并相应地更改其他?
    【解决方案2】:

    两个问题。首先,

    A a(); 
    

    是一个函数声明。你需要

    A a;
    

    那么,

    fl.push_back(std::bind(&A::Func1, &a, 1,1));
    

    【讨论】:

    • 我相信您需要在A::Func1 之前添加一个额外的&amp;
    【解决方案3】:

    你也可以不使用std::bind()

    std::vector<std::function<void(void)>> fl;
    A a{};
    fl.push_back([&](){ a.Func1(1, 1); });
    

    代码显示堆栈上的引用a。当函数对象没有超过a 时,这没关系。如果不能保证,您可能希望将&amp; 替换为=,这将复制对象。顺便说一句,从(){} 的细微变化导致代码将a 声明为A 类型的对象,而不是作为不带参数并返回A 的函数。

    【讨论】:

    • 好吧,有什么不同吗?优点/缺点?
    • @Solrik:有什么区别? std::bind() 与 lambda 函数? lambda 函数的优点是调用不通过函数指针,并且有更好的内联机会。并不是说这将是一个主要的区别,因为std::function&lt;...&gt; 无论如何都会调用virtual(或类似的东西)。此外,lambda 函数将只复制所有绑定/捕获的参数一次,而它取决于 std::bind() 的实现,绑定参数的复制频率(我不知道当代的实现有多好)。
    • v 是什么类型?
    • 这显然是你的std::vector&lt;std::function&lt;void(void)&gt;&gt;。好像你叫它fl(我会更新答案)。
    【解决方案4】:

    不幸的是,C++ 没有这样的语法。具有正确语法的完整示例如下所示:

    #include <iostream>
    #include <vector>
    #include <functional>
    
    using namespace std;
    
    class A
    {
    public:
        A() {}
        void Func1(int,int) {}
        void Func2(long,long) {}
    };
    
    
    int main() 
    {
    
        std::vector<std::function<void(void)>> fl;
        A a;
        fl.push_back(std::bind(&A::Func1, &a, 1,1));
        return 0;
    }
    

    你需要提供两件事(至少):1)指向成员函数的指针 2)隐含的“this”指针,即你要调用方法的对象。

    然后你可以添加你要绑定的参数。

    还请注意,不幸的是,您无法使用“A a();”创建“A”的实例这是“最令人头疼的解析”。正确的方式是“A a;”或“一个{};”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      • 2021-04-19
      • 2015-07-14
      • 1970-01-01
      相关资源
      最近更新 更多