Evyatar
Evyatar

Reputation: 1157

Map to method c++11

I'm tried to make a map to class methods using C++11's function.

The C-Style function pointers:
Method:

void MyClass::MyMethod(void*);

Map declare:

std::map<int, void (MyClass::*)(void*)> mapIdToMethod;

Map insert:

mapIdToMethod.insert(std::make_pair(2, &MyClass::MyMethod));

Method call:

MyClass mc;
(mc.*mapIdToMethod.at(1))(nullptr);

The code above is worked, But how can I convert it to use C++11's function?
What i'm tried:
Map declare:

std::map<int, function<void(void*)>> mapIdToMethod;//The map declare

Now, how can I insert and call the method on this map?

Upvotes: 3

Views: 2339

Answers (2)

MarkusParker
MarkusParker

Reputation: 1596

Probably not as efficient as the original but maybe easier to read:

std::map<int, std::function<void (MyClass&,void*)>> mapIdToMethod;    
mapIdToMethod.emplace(2, [](MyClass& c,void* p){ c.MyMethod(p);});
// alternatively:
using std::placeholders::_1;    
using std::placeholders::_2;
mapIdToMethod.emplace(2,std::bind(&MyClass::MyMethod,_1,_2));

MyClass mc;
mapIdToMethod.at(2)(mc, nullptr);

Upvotes: 4

Jonathan Mee
Jonathan Mee

Reputation: 38919

I am also a fan of function over C-style pointers, but it's important that you recognize that the analog for void (MyClass::*)(void*) is function<void(MyClass&, void*)> not function<void(void*)>. So you could replicate what you've already have going in MapIdToMethod with:

map<int, function<void(MyClass&, void*)>> bar;

You could insert to this the same way as you inserted to MapIdToMethod (bar.insert(make_pair(2, &MyClass::MyMethod)), but you could also use mem_fn, which wouldn't have been possible to use when inserting to MapIdToMethod:

bar.insert(make_pair(2, mem_fn(&MyClass::MyMethod)));

Now, to answer your question. Given:

map<int, function<void(void*)>> foo;

You can insert member functions which take a void* and don't return anything, but only if you already have the object on which you wish to make the calls constructed. You can do that using bind:

MyClass mc;

foo.insert(make_pair(2, bind(&MyClass::MyMethod, mc, placeholders::_1)));

Live Example

Upvotes: 2

Related Questions