2013-07-03 133 views
0

我的问题不是我不能映射到函数指针,而是更多的方式。std ::映射函数指针

用我目前的设置,我可以通过字符串实例化类。 现在,我试图从类类型中获取字符串。

我提出的方法:

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)

我知道我可以使用的dynamic_cast <>检查实体类型,但这需要为每个将被用于类编写代码。

+0

哪里是'模板创建()'声明/定义? –

+0

哎呀,有“构造”和“创造”混合起来。固定。 – object

+0

尝试为该问题创建一个[SSCCE](http://sscce.org) - 您提供的代码不完整,并且当您填写不完整的部分时,它会编译/正常工作... –

回答

0

问题是create()返回的类型与映射的返回类型指定的模板参数不同。由于所有内容都使用A作为基本类型,因此您应该考虑使用create()

template <typename T> A* create(void) { return new T; } 
        ^^^^ 
+0

使感觉,但它不是在分配字符串的值到函数指针时做同样的事情吗? – object

+0

是的,如果你绑定到派生自'A'的类型,你将得到一个关于无效转换的类似错误。 –

0

我已经做了类似的事情,就是将字符串映射到任何类型的函数指针。从我的答案,张贴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; 
}