My issue here is not that I can't map to function pointers, but more the other way around.
With my current setup, I can instantiate classes through strings. Now, I'm trying to get strings from class types.
My proposed method:
class A {};
template <typename T> T* create(void) { return new T; }
static std::map<std::string,A*(*)(void)> str_to_class;
static std::map<A*(*)(void),std::string> class_to_str;
template <typename T> void Bind(std::string identity) {
// T must inherit from A.
str_to_class[identity]=&create<T>;
class_to_str[&create<T>]=identity;
}
A* MakeFromString(std::string identity) {
return str_to_class[identity](); // Compiles fine.
}
template <typename T> std::string GetTypeString(void) {
return class_to_str[&create<T>]; // Error!
}
int main(int,char**) {
Bind<A>("A");
A* new_entity=CreateFromString("A");
}
Error: C2679: binary '[' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)
I know I can use dynamic_cast<> to check entity types, but that would require writing code for every class that would be used.
The problem is that create()
returns a type different than what is specified as the return type of the maps key template argument. Since everything uses A
as the base / primary class type you should consider doing the same for create()
.
template <typename T> A* create(void) { return new T; }
^^^^
I have done something similar which is about mapping string to function pointer of any type. From my answer which was posted here :
#include <string>
#include <iostream>
#include <map>
#include <vector>
int fun1(){
std::cout<<"inside fun1\n";
return 2;
}
void fun2(void){
std::cout<<"inside fun2\n";
}
int fun3(int a){
std::cout<<"inside fun3\n";
return a;
}
std::vector<int> fun4(){
std::cout<<"inside fun4\n";
std::vector<int> v(4,100);
return v;
}
// every function pointer will be stored as this type
typedef void (*voidFunctionType)(void);
struct Interface{
std::map<std::string,voidFunctionType> m1;
template<typename T>
void insert(std::string s1, T f1){
m1.insert(std::make_pair(s1,(voidFunctionType)f1));
}
template<typename T,typename... Args>
T searchAndCall(std::string s1, Args&&... args){
auto mapIter = m1.find(s1);
/*chk if not end*/
auto mapVal = mapIter->second;
// auto typeCastedFun = reinterpret_cast<T(*)(Args ...)>(mapVal);
auto typeCastedFun = (T(*)(Args ...))(mapVal);
return typeCastedFun(std::forward<Args>(args)...);
}
};
int main(){
Interface a1;
a1.insert("fun1",fun1);
a1.insert("fun2",fun2);
a1.insert("fun3",fun3);
a1.insert("fun4",fun4);
int retVal = a1.searchAndCall<int>("fun3",2);
a1.searchAndCall<void>("fun2");
auto temp = a1.searchAndCall<std::vector<int>>("fun4");
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.