Using a Stl Map of Function Pointers

Using a STL map of function pointers

Whatever your function signatures are:

typedef void (*ScriptFunction)(void); // function pointer type
typedef std::unordered_map<std::string, ScriptFunction> script_map;

// ...

void some_function()
{
}

// ...

script_map m;
m.emplace("blah", &some_function);

// ...

void call_script(const std::string& pFunction)
{
auto iter = m.find(pFunction);
if (iter == m.end())
{
// not found
}

(*iter->second)();
}

Note that the ScriptFunction type could be generalized to std::function</* whatever*/> so you can support any callable thing, not just exactly function pointers.

Map containing function pointers in C++

This is a similar question, the answer should be useful:
answer showing heterogeneous function map

The answer shows how to call functions in the map.

How to store methods as function pointers in a map container?

You can use std::function with a lambda or std::bind :

class reader
{
std::map<std::string, std::function<void()>> functionCallMap;

void readA() { std::cout << "reading A\n"; };
void readB() { std::cout << "reading B\n"; };

public:
reader()
{
functionCallMap["A"] = [this]() { readA(); };
functionCallMap["B"] = std::bind(&reader::readB, this);
}

void read()
{
functionCallMap["A"]();
functionCallMap["B"]();
}
};

std::map of member function pointers?

This is about the simplest I can come up with. Note no error checking, and the map could probably usefully be made static.

#include <map>
#include <iostream>
#include <string>
using namespace std;

struct A {
typedef int (A::*MFP)(int);
std::map <string, MFP> fmap;

int f( int x ) { return x + 1; }
int g( int x ) { return x + 2; }


A() {
fmap.insert( std::make_pair( "f", &A::f ));
fmap.insert( std::make_pair( "g", &A::g ));
}

int Call( const string & s, int x ) {
MFP fp = fmap[s];
return (this->*fp)(x);
}
};

int main() {
A a;
cout << a.Call( "f", 0 ) << endl;
cout << a.Call( "g", 0 ) << endl;
}

How can i put function with different parameters into map in c++?

What you're asking is essentially the same as:

How can I store both int and float in a map and use them equally?

Functions with different parameters are simply different. A map can only hold a single type. Suppose you get function "2019", how will you or the compiler ever know what kind of function it is?

There are a couple of ways to solve this problem. The essence is to have them be the same type. With std::bind you're on the right track. The correct way to use bind with parameters is to use the std::placeholders.

Say we have this function, double DoThing(int num, std::vector<float>& vec), and wish to fill in the first parameter, but leave the second one open for later. We can do:

mymap.emplace("2000", std::bind(&DoThing, 123, std::placeholders::_1));

You are free to shift the placeholder around however you like and add other ones too.
If you store the object bind returns and later get it back you can call it like so:

mymap["2000"](vec);  //will call  DoThing(123, vec)

Also. std::bind returns an object that holds both the function pointer to DoThing and any value you prefilled as well. Casting this to a function pointer like you did is not possible. That object is not a problem here since std::function, the map's contained type, has functionality to also store and, later, be able to call this object correctly.

Simillarly you can use lambda's to achieve the same effect as bind:

mymap.emplace("2000", [](std::vector<float>& vec){ return DoThing(123, vec); });

Other possibilities include unions/variants or other possibly tricky stuff. Though these methods will only make your code more complex if you don't know how to use them, so I don't recommend these.

Storing function pointers in a std::map

You need to specify comparator for _timeset for std::map to work, for example:

struct _timeset
{
int hr1;
int min1;
int secs1;
bool operator<( const _timeset &t ) const {
return std::make_tuple( hr1, min1, secs1 ) < std::make_tuple( t.hr1, t.min1, t.secs1 );
}
};

or you can make it as lamba as described here

Also while iterating the map, can I execute the relevant function with something like

yes you can, also you do not have to copy your struct _timeset:

int i = 0;
for ( it1 = m1.begin(); it1 != m1.end(); it1++,i++)
{

const _timeset &_t = it1->first;
//Check Values in _t, and then execute the corresponding function in the map

(*it1->second)();
}

if you want to store functions with different signature, use std::function:

typedef std::function<void()> func;
std::map<_timeset, func> m1;

void fun1();
void func2( int );
struct foobar { void func3(); };

m1.insert( std::make_pair( t, func1 ) ); // signature matches, no need for bind
m1.insert( std::make_pair( t, std::bind( func2, 123 ) ) ); // signature does not match func2(123) will be called
foobar *pf = ...;
m1.insert( std::make_pair( t, std::bind( func3, pf ) ) ); // signature does not match, pf->func3() will be called
// etc


Related Topics



Leave a reply



Submit