【问题标题】:How to pass a functionpointer when the arguments are not known yet当参数未知时如何传递函数指针
【发布时间】:2015-12-21 09:59:03
【问题描述】:

我有一个静态函数Bar::Function(std::string s1, std::string s2, std::string s3 ),我想将它作为函数指针传递给具有boost::function 成员的类Foo 的构造函数。

但这三个字符串是在Foo() 类中创建的,尚不知道该函数何时作为函数指针传递给 Foo 的构造函数。 我应该像在main() 中那样简单地传递三个空字符串吗?

class Foo(boost::function<int(std::string, std::string, std::string)> fFunction)
{
public:
    Foo()
    {
        fnCallback = fFunction;
    }

    int Call()
    {
        return fnCallback("first", "second", "third")
    }
protected:
     boost::function<int(std::string, std::string, std::string)> fnCallback;
};


int main(int /*nArgc*/, char */*paszArgv*/[])
{
    boost::function<int(std::string, std::string, std::string)> fn = boost::bind(Bar::Function, "", "", "");
    Foo oFoo(fn);
    oFoo.Call();
    return 0;
}

class Bar
{
public:
    static int Function(std::string s1, std::string s2, std::string s3)
    {
        std::cout << s1 << s2 << s3 << std::endl;
    }
};

编辑:这就是代码的外观。函数指针只保存函数的地址。调用时传递参数!

fn = &Bar::Function;

【问题讨论】:

  • 当你传递一个函数指针时,它没有参数。
  • 我发布了示例代码。顺便说一句,有很多语法错误...
  • 这个问题是XY problem 的经典例子。您不需要为此使用boost::function。 (事实上​​,你不想为此使用boost::function。)一个简单的函数指针就足够了。

标签: c++ function-pointers boost-function


【解决方案1】:

这是一个最小的例子:

#include <iostream>
#include <string>

struct Foo
{
    typedef int (*callback_type)(std::string, std::string, std::string);

    Foo(callback_type callback)
        : _callback(callback)
    {}

    int operator()()
    {
        return _callback("1", "2", "3");
    }

private:
     callback_type _callback;
};

struct Bar
{
    static int Function(std::string s1, std::string s2, std::string s3)
    {
        std::cout << s1 << s2 << s3 << std::endl;
        return 0;
    }
};

int main()
{
    Foo foo(Bar::Function);
    foo();
    return 0;
}

打印123\n

【讨论】:

    【解决方案2】:

    我认为您需要使用std::placeholders::_1std::placeholders::_2std::placeholders::_3,而不是空白字符串。如果是我,我愿意关注,

    https://gist.github.com/yasuharu519/213307b4709662e60df2

    #include <functional>
    #include <iostream>
    #include <string>
    
    class Foo
    {
    public:
      Foo(std::function<int(std::string, std::string, std::string)> fFunction) : fnCallback{fFunction} {}
      int Call() { return fnCallback("first", "second", "third"); }
    
    protected:
      std::function<int(std::string, std::string, std::string)> fnCallback;
    };
    
    class Bar
    {
    public:
      static int Function(std::string s1, std::string s2, std::string s3)
      {
        std::cout << s1 << s2 << s3 << std::endl;
        return 0;
      }
    };
    
    int main(int /*nArgc*/, char* /*paszArgv*/ [])
    {
      using namespace std::placeholders;
      auto fn = std::bind(Bar::Function, _1, _2, _3);
      Foo oFoo(fn);
      oFoo.Call();
      return 0;
    }
    

    【讨论】:

    • Bar::Function 是一个静态函数。不需要占位符:Foo oFoo(Bar::Function).
    • 我不是反对者;这在技术上是正确的。然而,这太过分了。在这种情况下,不需要使用 std::bind 或占位符。
    • 虽然在此处显示的特定情况下是正确的,但 OP 很可能已经简化了他们的代码来提出问题(这是一件好事!) - 但不知不觉地简化了很多,以至于他们最干净答案变了。因此,占位符可能正是他们需要的!
    猜你喜欢
    • 1970-01-01
    • 2011-12-23
    • 2012-11-26
    • 1970-01-01
    • 2019-11-01
    • 2012-05-03
    • 1970-01-01
    • 2015-01-29
    • 2017-10-18
    相关资源
    最近更新 更多