C ++ map <char, static method pointer>?
I wrote a very simple expression parser and would like it to be extensible so that it can parse custom expression types. For example, if during parsing I encounter a < character, I want to create an instance of the class used to parse expressions starting with this character.
I have two questions:
How to associate a character with a pointer to a static method?
I want to use a static method that will return a new instance of the class, since I cannot get a pointer to the constructor of the class. The following syntax is probably incorrect, but the idea is:
typedef static IValue * (*returnPtrIValue)(); map<char, returnPtrIValue> ...Assuming I have class A and class B extends class A, can I initialize a pointer to a function that returns a / ref pointer to with a pointer to a function that returns a / ref pointer to B with a B is A?
For example, can I do:
typedef A * (*returnPtrA)(); B * func() { ... } returnPtrA foo = func;
This thread helped me do what I wanted: Dynamically create class objects? Thank you for your responses!
1: remove static from your typedef, for example:
typedef IValue * (*returnPtrIValue)(); A pointer to a static member function can then be bound to a variable (or placed on a map) of this type, for example:
returnPtrIValue fun = &SomeClass::somestaticfun; Is this what you are asking for?
2: Generally speaking, no. Not by type, at least. Covariance does not work in C ++ in this way.
If you really want to do this, you can do it either with reinterpret_cast or with some hackers with associations, but this may be compiler dependent and I would not recommend it (I can give you some advice if you want to).
UPDATE: Here is a really good article that explains how to implement delegates in C ++ using (member) in C ++. He delves deeply into the question, and I found that the first half of them is a pretty good reference / explanation (member) of function pointers in C ++ and how to work with them. I suggest checking this out if you are interested in understanding how they work in C ++.
1) Just remove static from your typedef, the "static method" is like a simple function (only declared inside the scope of the class).
2) It seemed legal, but unfortunately I get a compiler error:
error: invalid conversion from 'B* (*)()' to 'A* (*)()' It seems that function pointers do not support covariant return types ...
This code should answer your questions, even if not for sure. In fact, I solved some of your problems using virtual calls (be careful: performance issues).
#include <iostream> #include <map> struct parse_result { // something here }; class parser { public: virtual parse_result parse() = 0; }; class parser1 : public parser { public: parse_result parse() { // something here std::cout << "Called parser1::parse()" << std::endl; return parse_result(); } }; class parser2 : public parser { public: parse_result parse() { // something here std::cout << "Called parser2::parse()" << std::endl; return parse_result(); } }; static parser1* make_parser1() { return new parser1(); } static parser2* make_parser2() { return new parser2(); } typedef parser* (*parser_factory_method)(); int main() { std::map<char, parser_factory_method> parsers; parsers.insert(std::make_pair('1', (parser_factory_method) make_parser1)); parsers.insert(std::make_pair('2', (parser_factory_method) make_parser2)); for (auto entry : parsers) { std::cout << "Calling parser for " << entry.first << std::endl; parser_factory_method pfm = entry.second; parser* p = pfm(); p->parse(); // parse_result is ignored here, but can be used as needed delete p; } return 0; } Please note that I do not like this design for the parser. It somehow mimics the reflection of Java, and it is doomed to performance problems. See if you can clarify it.