I've tried various solutions on SO to solve this problem, yet I must be doing something wrong.
I have several classes where methods in each of the classes have the same method signature:
typedef int (*ControllerMethod)(const std::string &data, const std::unordered_map<std::string, std::string> ¶ms);
And an example class having some method using that signature:
class StaticContentController {
public:
int handleStaticContentRequest(const std::string &data, const std::unordered_map<std::string, std::string> ¶ms) {
return 1;
}
}
Now I try to create a map of pointers to member functions:
std::map<std::string, ControllerMethod> operations;
operations.emplace("staticContent", &StaticContentController::handleStaticContentRequest);
std::string d("test.txt");
ControllerMethod f = operations["staticContent"];
auto s = ((_staticContentController).*f)(d, pooledQueries); // <- compile error here
but calling the method gives the compile error
Right hand operand to .* has non-pointer-to-member type 'web::server::ControllerMethod'
What am I missing?
Update:
I now have an empty Controller base class which other controller classes inherit from:
namespace web { namespace server {
class Controller {
};
typedef ControllerResponse (Controller::*ControllerMethod)(const std::string &data, const std::unordered_map<std::string, std::string> ¶ms);
}}
Now I'm getting the following error at operations.emplace():
No matching constructor for initialization of 'std::__1::pair<const std::__1::basic_string<char>, web::server::ControllerResponse
Updated answer
You're trying to use two different paradigms here, and they aren't really compatible with one another. If I interpret your edit correctly, you're trying to create a map of functions that call into other classes, and you want to declare this map as a set of function pointers.
Function pointers are an assembly level construct, exposed by C. The syntax reflects this - and getting a C++ class to conform to this is not possible without help - namely, adding a context pointer parameter that is associated with every function pointer, and converting the context pointer to a class instance to call the member function.
So, how do we fix the problem?
In both of the next approaches, we need a context object associated with the function table. This involves creating a structure to hold the member function and the context:
template<typename T> struct FunctionTableEntry
{
ControllerMethod Function;
T* Context;
};
and our function pointer becomes the following:
typedef ControllerResponse (T::*ControllerMethod)(const std::string &data, const StringMap ¶ms);
Here, StringMap is a typedef for std::unordered_map<std::string, std::string>.
Our main problem now comes with removing the template parameter T, as we can't make maps of runtime defined templates (a template who's type will only be known at run time).
There are two main approaches to take in resolving this, and both have issues that will need to be considered. The first is to perform C style type erasure with pointers and very careful association. The second is to abandon function pointers in favor of C++ function objects.
C-Style Type Erasure
This option involves using C-style casts to convert the class instance pointer to its base class type, the member function pointer to the type expected by the function declaration, and then making the call as though the base class defines the method. This requires the use of pointers, and cannot be done without them.
To do this, our FunctionTableEntry structure changes to the following:
struct FunctionTableEntry
{
ControllerMethod Function;
Controller* Context;
}
and our function pointer to:
typedef ControllerResponse (Controller::*ControllerMethod)(const std::string &data, const StringMap ¶ms);
To add a new entry, we do the following:
std::map<std::string, FunctionTableEntry> operations;
FunctionTableEntry Entry;
Entry.Function = (ControllerMethod)&StaticContentController::handleStaticContentRequest;
Entry.Context = (Controller*)&_staticContentController;
operations.emplace("staticContent", Entry);
And to call it:
FunctionTableEntry f = operations["staticContent"];
auto s = ((f.Context)->*f.Function)(d, pooledQueries);
This method suffers from a few drawbacks - first, you have no other choice but to use pointers to refer to your controller objects - casting will not function properly otherwise. You can make this a bit more C++ friendly with std::shared_ptr, but otherwise, there is no way to replace it. This also means you need to carefully manage the lifetime of your controller objects. If they get freed while the function table is still referencing them you will almost certainly crash the system.
Second, the casting can cause issues with complex inheritance hierarchies. This method only works if (Controller*)_staticContentController == _staticContentController, i.e. casting to the base class gives the same numerical pointer value. Otherwise, the called method will fail as it will not be able to properly reference its local data.
This method has the advantage of being quite fast, however. There is no function overhead besides the table lookup, and the generated assembly is not much more than just calling the function normally. It is also runtime independent - so long as the equality expression above is true with all users of the controller system, anyone with a C++ compiler can create a new controller and this system will be able to call their functions, even if they use a completely different runtime library.
Additionally, if you know the controller instance is going to be used with multiple functions, you can modify the structure to provide a map of functions associated with one Context value, allowing you to reduce some of the memory overhead. This may not be possible with your design, but it's worth looking into if memory is a concern.
C++ Function Objects
The second solution is to completely do away with C-style function pointers altogether and use std::function. Since std::function can contain instance data as part of itself, and can be placed into a map, this allows you to std::bind a member function, creating a partially specified function call (I believe in functional programming this is what's called a closure).
In this case, there is no FunctionTableEntry structure - instead we use the following:
typedef std::function<ControllerResponse(const std::string&, const StringMap&)> ControllerMethod;
To add a new method, we do the following:
std::map<std::string, ControllerMethod> operations;
operations.emplace("staticContent", std::bind(&StaticContextController::handleStaticContentRequest, &_staticContentController, std::placeholders::_1, std::placeholders::_2);
This creates a closure that calls the member function with the required controller instance.
To call this, we do the following:
std::string d("test.txt");
ControllerMethod f = operations["staticContent"];
auto s = f(d, pooledQueries);
C++ function objects override operator (), which allows them to work as though they were static functions.
This method allows for both member functions and static functions to exist in the same map. It also allows for complex inheritance hierarchies to occur, as there is no casting to make things function - everything occurs with template functions.
The downside to this method is you still need to deal with object lifespan - the content controller objects cannot be destroyed until after the function map has been cleared. In addition, there is some overhead due to the use of std::function with placeholder parameters (though that likely depends on the runtime library in use, my tests have shown it generates a whole lot more code in x86-64 GCC 9.3).
This method also is not runtime independent - whatever runtime you choose to use here must also be used by every programmer that uses this code, otherwise incompatibilities in the way each library creates and stores std::function will cause strange failures. This means no compiler mixing - if you used MSVC 2019 to build the API, everyone else who uses this library must use MSVC2019 to build their controller component. If you aren't providing an API here, then this is not an issue.
Original answer
Your function pointer declaration is wrong - pointers to members have a different syntax to the normal function pointer typedef.
A normal function pointer uses the syntax you have currently:
typedef int (*foo)(int x, int y);
A pointer to member function typedef looks like this:
typedef int (SomeClass::*foo)(int x, int y);
The SomeClass:: section is required as pointers to members have an additional parameter to them, called this. In C++, the this pointer is passed as the first argument to the function, which makes the function declaration different (as the actual assembly code needed to call the function is different, see MSVC generated assembly for a real world example).
To solve the issue, you need to provide a base class that can be used to declare the typedef, then inherit from that class to allow the method to be called. This is effectively identical to using inheritance, unless you have multiple methods in the same type that have the same signature, but do different things.
The DirectX 11 Effects framework uses this exact paradigm to avoid branching when configuring different shader types in the graphics pipeline - see here, at line 590.
As pointed out, the type of a non-static member function of the class StaticContentController is not:
typedef int (*ControllerMethod)(const std::string &data, const std::unordered_map<std::string, std::string> ¶ms);
Instead, it is:
typedef int (StaticContentController::*StaticContentControllerMethod)(const std::string &data, const std::unordered_map<std::string, std::string> ¶ms);
This was your initial error.
This makes sense as you need an instance to call the member function, and the instance has a type as well. And it makes sense that if you have a Base::*Function pointer, you can call it with an instance of a class publicly and unambiguously derived from Base, because a derived pointer can be converted implicitly to a base pointer.
It also makes sense that you cannot assign a Derived::*Function pointer to a Base::*Function pointer because the result could be called with any Base instance, which need not be a Derived instance. This was the error in the question update.
In this very limited circumstance, C++ behaves completely logically.
With the modification to the correct type, your snippet will compile:
std::map<std::string, StaticContentControllerMethod> operations;
operations.emplace("staticContent",
&StaticContentController::handleStaticContentRequest);
std::string d("test.txt");
StaticContentControllerMethod f = operations["staticContent"];
auto s = ((_staticContentController).*f)(d, pooledQueries); // <- works
So presumably your actual question is how to store in this map member function pointers for multiple classes and not just StaticContentController. But that is the wrong question. You have to have the instance (_staticContentController) to invoke the member function pointer, so you already know the type.
So maybe you want to ask how to erase the type. One way is storing something that doesn't require an instance: for that, use std::function as the mapped type and bind the instance when inserting into the map. That would work and be straightforward if you have the controller at the time the map is created. A second way is using a type erasing type like std::any for the mapped type, and use any_cast at the point of use to return it to its initial type. A third way is to use a common base class with virtual functions which are overridden in your classes. Since the virtual functions can be called with a base pointer, you can store member function pointers of the base class.
Alternatively, maybe you want to ask how to have a type-indexed collection: the type is known at lookup time (because you have an instance) and you need to lookup a value whose type (member function pointer) depends on the "key" type.
The simplest way to do this is to have templated classes, and let the compiler handle the mapping:
template<typename T>
struct operations {
static std::map<std::string, void (T::*)(etc.)> pointers;
};
// use:
operations<StaticContentController>::pointers["staticContent"];
Another version of type-indexing might have the following interface:
template<template<typename> typename Value>
class type_keyed_map
{
public:
template<typename T>
void insert(std::unique_ptr<Value<T>> value);
template<typename T>
auto find() -> Value<T>*; // return null if not found
};
You can use a std::map in the implementation, but std::map does not allow multiple value types.
Related
What is the purpose of std::function? As far as I understand, std::function turns a function, functor, or lambda into a function object.
I don't quite understand the purpose of this... Both Lambdas and Functors are function objects already and I do believe that they can be used as predicates for algorithms like sort and transform. As a side note, Lambdas are actually Functors (internally). So the only thing I can see std::function being useful for is to turn regular functions into function objects.
And I don't quite see why I would want to turn a regular function into a function object either. If I wanted to use a function object I would have made one in the first place as a functor or lambda... rather than code a function and then convert it with std::function and then pass it in as predicate...
I'm guessing that there is much more to std::function... something that isn't quite obvious at first glance.
An explanation of std::function would be much appreciated.
What is the purpose of std::function? As far as I understand, std::function turns a function, functor, or lambda into a function object.
std::function is an example of a broader concept called Type Erasure. The description you have isn't quite accurate. What std::function<void()> does, to pick a specific specialization, is represent any callable that can be invoked with no arguments. It could be a function pointer or a function object that has a concrete type, or a closure built from a lambda. It doesn't matter what the source type is, as long as it fits the contract - it just works. Instead of using the concrete source type, we "erase" it - and we just deal with std::function.
Now, why would we ever use type erasure? After all, don't we have templates so that we can use the concrete types directly? And wouldn't that be more efficient and isn't C++ all about efficiency?!
Sometimes, you cannot use the concrete types. An example that might be more familiar is regular object-oriented polymorphism. Why would we ever store a Base* when we could instead store a Derived*? Well, maybe we can't store a Derived*. Maybe we have lots of different Derived*s that different users use. Maybe we're writing a library that doesn't even know about Derived. This is also type erasure, just a different technique for it than the one std::function uses.
A non-exhaust list of use-cases:
Need to store a potentially heterogenous list of objects, when we only care about them satisfying a concrete interface. For std::function, maybe I just have a std::vector<std::function<void()>> callbacks - which might all have different concrete types, but I don't care, I just need to call them.
Need to use across an API boundary (e.g. I can have a virtual function taking a std::function<void()>, but I can't have a virtual function template).
Returning from a factory function - we just need some object that satisfies some concept, we don't need a concrete thing (again, quite common in OO polymorphism, which is also type erasure).
Could potentially actually use templates everywhere, but the performance gain isn't worth the compilation hit.
Consider a simple use case:
/* Unspecified */ f = [](int x, int y){ return x + y; };
f = [](int x, int y){ return x - y; };
int a = 42;
f = [&a](int x, int y){ return a * x * y; };
How would you specify /* Unspecified */?
Furthermore,
std::queue<of what?> jobs;
jobs.push_back([]{ std::cout << "Hi!\n"; });
jobs.push_back([]{ std::cout << "Bye!\n"; });
for(auto const &j: jobs) j();
What value_type should be kept in jobs?
Finally,
myButton.onClick(f);
What type does f have? A template parameter? Okay, but how is it registered internally?
In most uses that I've seen, std::function was overkill. But it serves two purposes.
First, it gives you a uniform syntax for calling function objects. For example, you can use an std::function instantiation to wrap an ordinary function that takes a single argument of a class type or a member function and the class object that it should be applied to without worrying about the different calling syntax.
struct S {
void f();
};
void g(const S&);
S obj;
typedef std::function<void()> functor1(&S::f, obj);
typedef std::function<void()> functor2(&g, obj);
functor1(); // calls obj.f()
functor2(); // calls g(obj);
Note that both functors here are called with the same syntax. That's a big benefit when you're writing generic code. The decision of how to call the underlying function is made within the std::function template, and you don't have to figure it out in your code.
The other big benefit is that you can reassign the function object that a std::function object holds:
functor1 = std::function<void>()>(&g, obj);
This changes the behavior of functor1:
functor1() // calls g(obj)
Sometimes that matters.
As far as I understand, std::function turns a function, functor, or lambda into a function object.
You pretty much summed it up, you can turn any of these into the same thing, an std::function, that you can then store and use as you wish.
When you are designing a class or an API in general you usually don't have a reason to restrict your features to just one of these, so using std::function gives the liberty of choice to the user of your API, as opposed to forcing users to one specific type.
You can even store different forms of these together, it's basically an abstraction of callable types with a given signature and a clearly defined semantic.
One example of where std::function can be very useful is in implementing an "observer pattern". So, for example, say you want to implement a simple "expression evaluator" calculator GUI. To give a somewhat abstract idea of the kind of code you might write against a GUI library using the observer pattern:
class ExprEvalForm : public GuiEditorGenerated::ExprEvalForm {
public:
ExprEvalForm() {
calculateButton.onClicked([] {
auto exprStr = exprInputBox.get();
auto value = ExprEvaluator::evaluate(exprStr);
evalOutputLabel.set(std::to_string(value));
});
}
};
Now, how would the GUI library's button class store the function that's passed to onClicked? Here, an onClicked method (even if it were templated) would still need to store somewhere into a member variable, which needs to be of a predetermined type. That's exactly where the type erasure of std::function can come into play. So, a skeleton of the button class implementation might look like:
class PushButton : public Widget {
public:
using ButtonClickedCallback = std::function<void()>;
void onClicked(ButtonClickedCallback cb) {
m_buttonClickedCallback = std::move(cb);
}
protected:
void mouseUpEvent(int x, int y) override {
...
if (mouseWasInButtonArea(x, y))
notifyClicked();
...
}
private:
void notifyClicked() {
if (m_buttonClickedCallback)
m_buttonClickedCallback();
}
ButtonClickedCallback m_buttonClickedCallback;
};
Using function object is helpful when implementing thread pool. You can keep no of available workers as threads and work to do as queue of function objects. It is easier to keep work to be done as function object than function pointers for example as you can just pass anything thats callable. Each time new function object appear in queue, worker thread can just pop it and execute by calling () operator on it.
I need to establish a hash table using a hasher different from the default one, so I write something like:
class foo {
public:
...
private:
struct myhasher {
size_t operator() (myclass bar) { return hash_calculation bar; }
}
static size_t hash_calculation (myclass bar) {
// do some calculation
}
hash_map<myclass, myhasher> myhashmap;
}
It works. Now for some reason I have to write a non-static member function to replace hash_calculation, say, it needs a non-static member of the class as an argument. Then the whole thing failed because I cannot use a non-static method in a nested struct.
This is somehow similar to another widely discussed problem: how to use a non-static function to do comparison or sorting. See for example:
Using a non-static class member inside a comparison function
and
C++ std list sort with custom comparator that depends on an member variable for the object instance . They both established a functor instead of a function as the comparator. However in my case this trick does not work because I need a class name inside the hash_map definition, not a specific struct object. What should I do? Thanks in advance for your help!
You can't. How is the hash_map supposed to know which instance of myhasher should be used when calling myhaser::hash_calculation?
hash_map isn't part of the standard C++ library, not even in C++11, so it's a custom class, and you have included no information about how it works. If there is a way for it to take some sort of constructor argument for which myhasher it should use, you're in luck. But it doesn't sound like it.
Also, you're using pass by value when you probably mean to pass in a const reference. Passing by value is likely going to be really slow and inefficient.
The standard "hash-map", i.e., std::unordered_map<K, V, H, E, A> takes a hash object of type H as constructor argument. A copy of this object is used to determine the hash for the object by way of the function call operator. This way can provide some context. Obviously, you were already using a non-static function call operator but you choose to delegate to a static member.
Is it possible to define a class which is not a class template and that can store (say upon construction) a reference to any particular type and retrieve it later via a getter method?
struct Wrapper {
template<typename T> Wrapper(const T& t): t_(t);
// How to store the reference??
};
Boost::variant is of course not a solution since its implemented as a class template. And I have no RTTI. (Its in HPC environment, performance is all!)
The getter() should be able to remember the type. So that auto can be used later.
The getter() should be able to remember the type.
It can't. You erased the type. That's what happens when you put a value of arbitrary type inside an object of a consistent type. It's called "type erasure": the original type is removed from the containing class.
One of the consequences of this is that the type cannot magically be recovered. You can't have a class that is initialized with a type on a per-instance basis, and then have one of its member functions return a different type based on how that particular instance was initialized.
C++ is a statically typed language. The return type of every function must be defined at compile time. It cannot change because of what you put into a class at runtime.
It can't remember the type.
I can't use RTTI.
Then what you want is a void*. RTTI is the only way to do recover the original value's type in a type-safe way. If you don't want type-safety, then you want a void*. All you would be doing is writing a wrapper around static_cast<T*>.
There's really no point in writing a wrapper around void* and static_cast. If that's what you want, and you're willing to accept the perils of using them (ie: breaking the type-system), then just use it. The reason boost::any exists is to provide a type-safe void*, so that at least you know when you're casting it wrongly.
boost::any http://www.boost.org/doc/libs/1_50_0/doc/html/any.html
std::vector<boost::any> many;
int i = 5;
std::string a = "5";
many.push_back(i);
many.push_back(a);
std::string res;
if (many[1].type() == typeid(std::string))
res = boost::any_cast<std::string>(many[1]);
I have to create objects of three-four classes, all inherited from one base class, but some of the objects need to have different behavior - like complete change of one function; I can do this through more inheritance and polymorphism, but it doesn't seem like a good idea.
My first solution was to use specialized templates(for every nonstandard case), but then I have though about lambdas as template parameter(like here: Can we use a lambda-expression as the default value for a function argument? ) and use them instead class method(like here: C++11 lambda and template specialization ) - for me it's much better solution, because I only have to pass lambda for every weird situation:
auto default_lambda = [&]() -> int {return this->Sth;};
template<typename functor = decltype(default_lambda)>
class SomeClass{
...
Problem is with this pointer - method which I want to change need access to non-static methods and lambda is defined outside of non-static method. Moreover, I can't pass reference to class to lambda, because it's a template class(or maybe I'm wrong?).
Of course, I can use specialized template or just function pointers, but I really like solution with lambdas and I consider it much more fine than my other ideas.
Is there any way to "avoid" this problem? Or maybe my idea was bad all along?
There are at least three obvious problems with your approach:
The class SomeClass won't get access to private members, i.e. use of this is out of question.
You attempt to bind this from the context but there is no context i.e. nothing bind to. You will have to pass the object to dealt with a function parameter.
You only specified a type of the function object but no instance, i.e. you won't be able to use it later.
That said, it seems you could just use the type of a custom function object type rather than some lambda function (sure, this is absolutely unsexy but in return it actually works):
struct default_lambda {
template <typename T>
int operator()(T const& o) const { return o.x(); }
};
template <typename F = default_lambda>
class SomeClass {
...
};
If you need complete change of one function, you have two choices:
One virtual function, using perhaps local classes + type erasure if you have many such objects and you don't want to create many namespace scope types:
std::function, which can be rebound later if you wish.
Example code for the first solution (you can even make this a template):
std::unique_ptr<my_base2> get_an_object()
{
class impl : public my_base2
{
void my_virtual_function() { blah blah; }
};
return std::unique_ptr<my_base2>(new impl);
}
Both are generally superior to templates in this situation (but without context it is hard to tell).
Before I was trying to map my classes and namespaces, by using static calls I succeded and now I need to map the functions of my classes because they will be used dynamically.
Firstly I was thinking to hardcode in the constructor so I can assign a std:map with the string of the name of function pointing to the function itself.
for example:
class A{
int B(){
return 1;
}
};
int main(){
A *a = new A();
vector<string, int (*)()> vec;
vector["A.B"] = a.B;
}
By that I have mapped the function B on A class, I know that I only mapped the function the instance and thats B is not static to be globally mapped.
But thats what I need, at somepoint someone will give me a string and I must call the right function of an instance of a class.
My question is if I only can do that by hardcoding at the constructor, since this is a instance scope we are talking or if there is somehow a way to do this in the declaration of the function, like here for namespaces and classes:
Somehow register my classes in a list
If I understand you correctly, you want your map to store a pointer that can be used to call a member function on an instance, the value being chosen from the map at run time. I'm going to assume that this is the right thing to do, and that there isn't a simpler way to solve the same problem. Quite often when you end up in strange C++ backwaters it's a sign that you need to look again at the problem you think you have, and see whether this is the only way to solve it.
The problem with using an ordinary function pointer is that a non-static member function is not an ordinary function. Suppose you could point to a member function with an ordinary function pointer, what would happen when you dereferenced that pointer and called the function? The member function needs an object to operate on, and the syntax doesn't provide a way to pass this object in.
You need a pointer to member, which is a slightly obscure feature with relatively tricky syntax. While an ordinary pointer abstracts an object, a pointer to member abstracts a member on a class; the pointer specifies which class member should be called, but not which object to obtain the member from (that will be specified when the pointer is used). We can use it something like this:
class B;
class A
{
B some_function()
{ /* ... */ }
};
B (A::* myval)() = A::some_function;
Here myval is a variable that indicates one of the members of class A, in this case the member some_function (though it could point to any other member of A of the same type). We can pass myval round wherever we want (e.g. storing it in an STL container, as in your example) and then when we want to call the function, we specify the instance it should be called on in order to locate the function:
A some_a;
B newly_created_b = (some_a.*myval)();
This works for a particular case, but it won't solve your general issue, because member pointers contain the class they refer to as part of the definition. That is, the following two variables are of entirely different types:
B (Foo::* first_variable)() = Foo::some_function;
B (Bar::* second_variable)() = Bar::some_function;
Even though both functions can produce a B when called without arguments, the two values operate on different classes and therefore you can't assign a value of one type to a variable of the other type. This of course rules out storing these different types in a single STL container.
If you're committed to storing these in a container, you'll have to go with a functor-based solution like Charles Salvia proposes.
If I understand you correctly, you're going to have a class like:
struct Foo
{
int bar();
};
And the user will input a string like "Foo::bar", and from that string you need to call the member function Foo::bar?
If so, it's rather awkward to code a flexible solution in C++, due to the static type system. You can use an std::map where the key is a string, and the value is a member function pointer, (or std::mem_fun_t object), but this will only work on a single class, and only on member functions with the same signature.
You could do something like:
#include <iostream>
#include <map>
#include <functional>
struct Foo
{
int bar() { std::cout << "Called Foo::bar!" << std::endl; }
};
int main()
{
std::map<std::string, std::mem_fun_t<int, Foo> > m;
m.insert(std::make_pair("Foo::bar", std::mem_fun(&Foo::bar)));
Foo f;
std::map<std::string, std::mem_fun_t<int, Foo> >::iterator it = m.find("Foo::bar");
std::mem_fun_t<int, Foo> mf = it->second;
mf(&f); // calls Foo::bar
}
just found(using google) a topic to the same question I had with an answer.
What is the simplest way to create and call dynamically a class method in C++?
I didn't try it yet but makes sense, I will ask again later if it doesn't work
ty!
Joe
I must call the right function of an instance of a class.
You need to call a specific method on an existing instance, or you need to create an instance of the appropriate type and call the method?
If it's the former, then you need a std::map or similar that lets you look up instances from their names.
If it's the latter, that's basically what serialization frameworks need to do in order to create the correct type of object when de-serializing, the object that knows how to read the next bit of data. You might take a look at how the Boost serialization library handles it:
boost.org/doc/libs/1_40_0/libs/serialization/doc/serialization.html
Are you doing this in some kind of tight loop where you need the efficiency of a good map? If so, then member function pointers (as you linked to above) is a good way to go. (At least it is after you work around the problem #Tim mentioned of keeping member function pointers to different types in the same collection ... let the language abuse begin!)
On the other hand, if this is in code that's user-driven, it might be more legible to just be totally uncool and write:
if( funcName=="A.b" )
{
A a;
a.b();
} else
// etc etc etc
For the higher-performace case, you can supplement the same approach with a parse step and some integer constants (or an enum) and use a switch. Depending on your compiler, you might actually end up with better performance than using member function pointers in a map:
switch( parse(funcName) )
{
case A_b:
{
A a;
a.b();
}
break;
}
(Of course this breaks down if you want to populate your list of possibilities from different places ... for example if each class is going to register itself during startup. But if you have that kind of object infrastructure then you should be using interfaces instead of pointers in the first place!)