2014-01-14 138 views
0

我需要能夠有一個基類,它可以存儲指向成員函數的指針,不僅適用於它自己的方法,還適用於子類。這裏是什麼,我想用lambda表達式的例子,但我希望能夠與成員函數來做到這一點:C++ 11:如何使用std :: mem_fn和繼承std :: bind

struct Base 
{ 
    void registerFunc(std::string const& name, std::function<void *(void *)> code) 
    { 
     functionTable_[name] = code; 
    } 

    void *invokeFunc(std::string const& name, void *arg) 
    { 
     auto x = functionTable_[name]; 
     auto func = std::bind(x, _1); 
     return func(arg); 
    } 

    Base() 
    { 
     registerFunc("hello", [this](void *arg) { printf("hello"); return nullptr; }); 
     invokeFunc("hello"); 
    } 
private: 
    std::unordered_map<std::string, std::function<void *(void *)>> functionTable_; 
}; 

struct Derived : Base 
{ 
    Derived() 
    { 
     registerFunc("world", [this] (void *arg) { printf("world"); return nullptr; }); 
     invokeFunc("world"); 
    } 

    // Instead of lambdas, I would like to be able to put member 
    // functions like this into the std::unordered_map of the Base class 
    void *memberFunc(void *arg) { printf("oyoyoy"; } 
}; 
+0

我在基類中看不到虛函數。你想使用多態嗎? – CashCow

+0

不,我不想使用多態 - 雖然functionTable_的目的與我所知的v-table非常相似。考慮一下通過線路接收到的數據會導致其中一個功能(「hello」或「world」)被執行的情況。你不能使用v表,你基本上必須建立你自己的。 – Badmanchild

+0

你在尋找語法'registerFunc(「world」,std :: bind(&Derived :: memberFunc,this,_1));'?不相關的,你的'invokeFunc'有點費力,可以簡單地寫成'return functionTable_ [name](arg);'。 – Casey

回答

2

的所有invokeFunc方法並不需要使用std::bind()首先,應至少檢查功能有:

void *invokeFunc(std::string const& name, void *arg) 
{ 
    auto &x = functionTable_[name]; 
    if(!x) return 0; 
    return x(arg); 
} 

但更好的辦法是使用std::map::find()我相信

其次,你可以使用std::bind()傳遞方法:

Derived() 
{ 
    registerFunc("world", [this] (void *arg) { printf("world"); return nullptr; }); 
    invokeFunc("world"); 
    registerFunc("method", std::bind(&Derived::memberFunc, this, _1))); 
    invokeFunc("method"); 
}