I've written a very basic expression parser and I would like it to be extendable so it can parse user defined expression types.
For exemple, if when parsing I meet the character <
, I want to create an instance of the class used to parse expressions starting by this character.
I have two questions:
How can I associate a character to a static method pointer?
I want to use a static method that will return a new instance of the class since I can't get a pointer to the class constructror. The following syntax is probably wrong, but that's the idea:
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 returning a pointer/ref to a A with a pointer to a function returning a pointer/ref to a B since a B is an A?
For example, can I do:
typedef A * (*returnPtrA)();
B * func() { ... }
returnPtrA foo = func;
1: Remove static
from your typedef, like:
typedef IValue * (*returnPtrIValue)();
Pointer to static member function can be then assigned to the variable (or be put into map) of that type , like:
returnPtrIValue fun = &SomeClass::somestaticfun;
Is this what you are asking for?
2: Generally speaking - no. Not in typesafe way, at least. Covariance does not work in C++ that way.
If you really want to do this you can do this is with either reinterpret_cast
or doing some hackery with unions, but this may be compiler-dependant and I wouldn't recommend that (I can give you some hints if you do want this anyway).
UPDATE: Here is the really good article, that explains how to implement delegates in C++ with help of (member) function pointers in C++. It delves pretty deeply into the question and I've found that the first half of it is pretty good reference/explanation of (member) function pointers in C++ and how to work with them. I suggest to check it out if you're interested in understanding how they work in C++.
1) Just remove static
from your typedef, a "static method" is like a simple function (only declared inside the scope of a class).
2) That seemed legit but unfortunately I get a compiler error:
error: invalid conversion from 'B* (*)()' to 'A* (*)()'
It seems that function pointers don't support covariant return types...
If you're using C++11, you can try something like this:
#include <map>
#include <functional>
...
std::map<char, std::function<parser*()>> m;
m['a'] = []{return new parser_for_a;};
This way you don't need to have any static methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With