2012-11-19 58 views
1

我不知道如何標題這個問題。我有一個基類和兩個繼承類:將函數指針插入具有多態返回類型的映射

class Base {}; 
class Action : public Base {}; 
class Title : public Base {}; 

現在,讓我們說,我有兩個函數返回要麼Action *Title *

Action *getAction() { return new Action; } 
Title *getTitle() { return new Title; } 

有什麼辦法把這兩個功能整合到一個地圖?像這樣:

int main() 
{ 
    std::map<std::string, Base *(*)()> myMap; 
    myMap["action"] = getAction; 
    myMap["title"] = getTitle; 

    return 0; 
} 

現在,我得到一個錯誤:

invalid conversion from `Action* (*)()' to `Base* (*)()' 

我可以改變的功能簽名總是返回基類,然後它的工作,但我不知道是否有另一種方法來解決這個問題。

+1

查看['std :: function'](http://en.cppreference.com/w/cpp/utility/functional/function),或作爲[Boost函數](http:// www .boost.org/doc/libs/1_52_0/doc/html/function.html)庫。 –

+1

或返回'Base *' –

+0

是否有可能得到這個問題的背景,就像你使用它的目的? – Gaminic

回答

2

如果你使用:

Base *getAction() { return static_cast<Base *>(new Action); } 
Base *getTitle() { return static_cast<Base *>(new Title); } 

,那麼你就不會得到這個錯誤。

std::function是由STL提供的多態函數指針包裝器。

當然,使用模板,您可以編寫自己的函數包裝器來存儲目標,傳遞參數並進行轉換。這已經完成了,在決定推出自己的產品之前,你應該認真考慮。除非你喜歡重新發明輪子或有非常特殊的要求。

+0

所以對於多態函數,只有'std :: function'或等價的Boost庫作爲解決方案提供? (即那是所有?) – cassava

+0

@cassava看到我的更新 –

+0

謝謝,我現在滿意我認爲:-) – cassava

1

由於概念證明我有這樣的代碼:

#include <iostream> 
#include <map> 
#include <functional> 

struct A 
{ 
    virtual void f() = 0; 
}; 

struct B : public A 
{ 
    void f() { std::cout << "B::f\n"; } 
}; 

struct C : public A 
{ 
    void f() { std::cout << "C::f\n"; } 
}; 

B* getB() { return new B; } 
C* getC() { return new C; } 

int main() 
{ 
    std::map<std::string, std::function<A*()>> m; 
    m["b"] = getB; 
    m["c"] = getC; 

    m["b"]()->f(); 
    m["c"]()->f(); 
} 

它泄漏內存,但它works