0

ここでの問題は、関数ポインターにマップできないことではなく、その逆です。

現在のセットアップでは、文字列を介してクラスをインスタンス化できます。今、クラス型から文字列を取得しようとしています。

私の提案した方法:

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<> を使用してエンティティ タイプをチェックできることはわかっていますが、それには、使用されるすべてのクラスのコードを記述する必要があります。

4

2 に答える 2

0

問題は、mapsキーテンプレート引数create()の戻り値の型として指定されているものとは異なる型を返すことです。すべてが基本/プライマリ クラス タイプとして使用されるため、 についても同じことを検討する必要があります。Acreate()

template <typename T> A* create(void) { return new T; }
                     ^^^^
于 2013-07-03T01:34:47.713 に答える
0

文字列を任意の型の関数ポインタにマッピングすることについて、同様のことを行いました。ここに投稿された私の答えから:

#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;
}
于 2015-11-20T23:07:28.420 に答える