At first it seemed clear that I shouldn't be able to do this, but then I discovered that it can be done with free functions.
Here is an example where I pass void() functions from Child to Parent. The parent calls the function when their Frame comes up.
I have figured out the syntax to pass free functions with arguments, but I can't figure out how to pass a member function of Child with an argument.
Please help.
#include <iostream>
#include <vector>
#include <map>
#include <functional>
void f_Free1() { std::cout << "Hi there hello. I'm a free function without arguments."; }
void f_Free2(int i) { std::cout << "Hi there hello. I'm a free function with an argument. It's " << i; }
class Parent
{
std::map<unsigned int, std::vector<std::function<void()>>> Tasks;
protected:
void addTask(unsigned int frame, std::function<void()> task) { Tasks[frame].push_back(task); }
public:
virtual ~Parent() {}
unsigned int Frame = 0;
void tick()
{
if (Tasks.count(Frame))
{
for (auto task : Tasks[Frame])
{
task();
}
}
Frame ;
}
};
class Child : public Parent
{
void f_Child1() { std::cout << "This is a private Child function without arguments. "; }
void f_Child2(int i) { std::cout << "This is a private Child function with an argument. It's " << i; }
public:
Child()
{
addTask(3, f_Free1);
addTask(5, [a = int(4)] () { f_Free2(a); } ); // THIS WORKS!!!
addTask(7, std::function<void()> { std::bind(&Child::f_Child1, this) });
addTask(9, std::function<void()> { std::bind([a = int(4)]() { &Child::f_Child2(a), this) } }); // CAN'T MAKE THIS WORK
}
};
int main()
{
Child child;
for (unsigned int i = 0; i < 12; i )
{
std::cout << "[" << child.Frame << "]";
child.tick(); // runs tasks whose frames are up
std::cout << std::endl;
}
return 0;
}
CodePudding user response:
Ditch the bind
.
Use [this]() { f_Child1(); }
and [this]() { f_Child(4); }
.
Also, the free version can be just []() { f_Free2(4); }
.
CodePudding user response:
std::bind
's syntax would be:
std::bind(&f_Free1)
std::bind(&f_Free2, 4)
std::bind(&Child::f_Child1, this)
std::bind(&Child::f_Child2, this, 4)
But lambda is simpler for most people:
&f_Free1
is fine, else[](){ return f_Free1(); }
[](){ return f_Free2(4); }
[this]() { return this->f_Child1(); )
[this]() { return this->f_Child2(4); )
return
can be omitted here as functions return void
.
this->
can be omitted in lambda.
you might capture more or differently for arguments.