2016-09-10 45 views
4

我正在爲遊戲引擎創建消息傳遞系統,其中引擎的最終用戶可以創建消息對象並將其傳遞給要由偵聽器對象解釋的遊戲對象包含附加到遊戲對象的組件。如果消息與偵聽器正在偵聽的消息相匹配,那麼偵聽器應該調用函數指針並將它接收到的消息傳遞給它。基本結構看起來像這樣:std :: function vs Lambda用於傳遞成員函數

class Message 
{ 
    std::string message; 
}; 

class Listener 
{ 
    std::string target; 
    void (*fn)(Message*); 
}; 

與遊戲對象的代碼,以接收消息看起來像這樣:

//if the queue is empty then dont do anything 
if (messageQueue.empty()) 
{ 
    return; 
} 

//else grab the front of the queue 
Message* newMessage = messageQueue.front(); 

//pop our message from the queue 
messageQueue.pop(); 

//for each component in our list 
for (std::vector<Component*>::iterator i = ComponentList.begin(); i < ComponentList.end(); i++) 
{ 
    Component* itemp = *i; 
    //for each message in its listener list 
    for (std::vector<Listener*>::iterator j = itemp->Listeners.begin(); j < itemp->Listeners.end(); j++) 
    { 
     Listener* jtemp = *j; 
     //check the listener against the newMessage 
     if (jtemp->name == newMessage->name) 
     { 
      //call jtemp's function 
      jtemp->function(newMessage); 
     } 
    } 
} 

,我已經跑進問題是,由於需要的功能被上面的代碼段調用的是組件類型的成員函數,我不能將Listener.fn設置爲等於Component::foo或任何其他函數。

我問我的同學們是否可以提供任何建議,我收到的兩條建議是使用lambdas或使用std::function將成員函數指針轉換爲常規函數指針。

我從來沒有用過lambda函數,但在研究here之後,如果我正確地掌握了它,好像我必須在每次傳遞一條消息時都要寫一個新的lambda,像這樣的系統。而經過研究std::functionhereherehere好像std::function會給我我需要的靈活性,但實現已經給了我大量錯誤

我俯瞰lambda表達式的力量,我應該使用std::function在這種情況下,如果是的話如何創建一個返回void和消息指針?

+0

您似乎已經找到了回答自己的問題所需的全部資源。我建議你嘗試使用它們,如果你仍然無法解決你的問題,請回答我們關於你遇到的錯誤的具體問題。 – Barry

+0

無論您使用什麼,都無法將成員函數指針轉換爲普通函數指針。 C++不提供此類轉換的任何標準功能。'std :: function'和lambda都不能幫助你達到目的。你可以改用'std :: function' *來代替函數指針,但這意味着你將不得不忘記「普通函數指針」。 – AnT

回答

4

std::function是存儲的正確解決方案。 std::function存儲幾乎任何與其簽名兼容的東西。

通常你會用lambda填充它。因爲這比bind或其他替代方案更容易和更清晰。

std::function<void(Message*)> fn; 

fn = [comp](Message * m){ comp->foo(m); }; 
0

根據我的經驗,如果您有權訪問C++ 11,請不要使用「經典」函數指針。在C++中編寫指向成員函數的指針是很複雜的。語法不直觀,並可能導致脫髮:如果Yakk說,std::function幾乎可以在任何情況下工作。 Lambda表達式雖然在語法上有些微不足道(lambda capture),但它非常有用。與std::function它們結合在一起,你也許可以實現任何你想要的X)

如果你仍然想使用傳統的函數指針,我推薦你讀這個線程(與本網站一般用於其他用途圍繞C++)循環:
https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types

相關問題