Reputation: 1833
I have a Sprite
class that has an int update(int key)
method.
I also have another class (SpriteManager
) that has a list of all Sprites
. I want to add a method to this class that takes a method, and an int as an argument. I then want to iterate through this list and call that method on all of the objects. However, I cannot find any way to do this. I know how to pass function as parameters, and also how to call specific methods on objects out of context, but I don't know how to do both.
An example of using this method would be something like:
sm.tellSpritesToDoSomething(Sprite::update, 42);
Where sm
is a SpriteManager
.
Upvotes: 0
Views: 76
Reputation: 2031
You should check std::bind, std::function and placeholders. And always remember that method itself is not enough, you need to pass object which will be used as this inside. For example
sm.tellSpritesToDoSomething(std::bind(&Sprite::update, _1, 42));
To other ways to do this are to use member function pointers (either explicitly or via templates):
#include <vector>
#include <algorithm>
#include <functional>
struct Sprite {
int update(int i) { return i; }
};
struct SpriteManager {
std::vector<Sprite> sprites;
template <typename F>
void tellSpritesToDoSomething(F f, int i) {
for (auto& sprite: sprites)
{
(sprite.*f)(i);
}
}
void tellSpritesToDoSomething2(int (Sprite::*f)(int), int i) {
for (auto& sprite: sprites)
{
(sprite.*f)(i);
}
}
void tellSpritesToDoSomething3(std::function<int(Sprite&)> f) {
std::for_each(sprites.begin(), sprites.end(), f);
}
};
int main() {
SpriteManager sm;
sm.sprites.emplace_back();
sm.sprites.emplace_back();
sm.sprites.emplace_back();
sm.tellSpritesToDoSomething(&Sprite::update, 42);
sm.tellSpritesToDoSomething2(&Sprite::update, 42);
using std::placeholders::_1;
sm.tellSpritesToDoSomething3(std::bind(&Sprite::update, _1, 42));
}
Upvotes: 4