tzippy
tzippy

Reputation: 6638

How to pass a functionpointer when the arguments are not known yet

I have a static function Bar::Function(std::string s1, std::string s2, std::string s3 ) that I want to pass as a functionpointer to the constructor of class Foo which has a boost::function member.

But the three strings are created in the Foo() class and not yet known when the function is passed as a functionpointer to the Foo's constructor. Should I simply pass three empty strings as I'm doing it in the 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;
    }
};

EDIT: This is how the code should look. The function pointer only holds the adress of the function. Arguments are passed when it is called!

fn = &Bar::Function;

Upvotes: 0

Views: 81

Answers (2)

YSC
YSC

Reputation: 40080

Here is a minimal example:

#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;
}

Prints 123\n.

Upvotes: 2

yasuharu519
yasuharu519

Reputation: 244

I think you need to use std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, instead of blank strings. If me, I would do like following,

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;
}

Upvotes: 1

Related Questions