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
Why Is Padding Added for Multiple Data Members of Structures and Not for Single Members
C++ Delete Vector, Objects, Free Memory
Make Shared_Ptr Not Use Delete
Undefined Symbols "Vtable for ..." and "Typeinfo For..."
Simple Illumination Correction in Images Opencv C++
Difference Between Char* and Char[]
Error When Compiling Some Simple C++ Code
Using \ in a String as Literal Instead of an Escape
What Is a Non-Trivial Constructor in C++
Why Isn't 'Int Pow(Int Base, Int Exponent)' in the Standard C++ Libraries
Find Argc and Argv from a Library
Find Out If String Ends with Another String in C++
Selecting a Member Function Using Different Enable_If Conditions
Is Right Shift Undefined Behavior If the Count Is Larger Than the Width of the Type
Checking for Null Pointer in C/C++
How Are Iterators and Pointers Related
Change Floating Point Rounding Mode
Access Variable Value Using String Representing Variable's Name in C++