How can Binder2nd objects that store pointers to member functions be used in a map?
My question is similar to this one. I need to store pointers to member functions in the map. The member functi开发者_如何学Pythonons takes an argument, which has to binded by a specific value while constructing the map. How do i do that? Should map have a binder2nd object as its value.
Eg:
enum { FOO, BAR };
exMap["foo"] = bind2nd(&classA::Func, FOO);
I don't know how to declare this map.
Here is an example that works using Boost.Function:
#include "boost/function.hpp"
#include <map>
#include <iostream>
#include <functional>
struct Foo {
void bar(int x) {
std::cout << "bar called with x=" << x << std::endl;
}
};
int main()
{
Foo foo;
std::map<int, boost::function<void (Foo*)> > m;
m[1] = std::bind2nd(std::mem_fun(&Foo::bar), 3);
m[1](&foo);
return 0;
}
Apparently this is not possible with binder2nd
, because it is not default-constructible, which is a requirement for the values of an std::map
.
Since you cannot use Boost, you will have to write your own binder.
Instead of bind2nd
you could do that manually with std::pair
. An Example:
#include <map>
#include <functional>
#include <string>
enum { FOO, BAR };
class classA{
public:
void Func(int){}
};
// define classAMemFn
typedef void (classA::*classAMemFn)(int);
// define element
typedef std::pair<classAMemFn, int> XElement;
typedef std::map<std::string, XElement> XMap;
void setup(XMap& xmap){
xmap["FOO"]=std::make_pair(&classA::Func,FOO);
xmap["BAR"]=std::make_pair(&classA::Func,BAR);
}
void Caller(XMap& xmap, const std::string& key, classA& obj){
XMap::iterator it=xmap.find(key);
if (it!=xmap.end()) {
XElement e=it->second;
(obj.*e.first)(e.second);
}
}
The setup
function 'binds' pointers to member functions and a parameter to a string key.
The Caller
function encapsulates the messy business of finding the pair in the map and performing the call.
As I understood from your comment to the question you need a mapping from string to enum and then you want to call a function with enum value.
If so, why you are complicating things with binders?
You can simply do something like:
// Initialize your map with appropriate string -> enum mappings.
and
callYourFunction(yourMap[yourStringFromInput]);
The type of the map would be:
std::map<std::string, YourEnumType> yourMap;
And function’s prototype:
SomeReturnType callYourFunction(YourEnumType e);
That’s it, no more binders ;)
精彩评论