2013-04-18 55 views
0

我正面臨有關函數指針語法的問題。我之前使用過這些,但是我已經讓事情變得完全不明顯了。指向STL映射中的函數的指針

因此,我正在設計一個爲遊戲創建節點的工廠。該工廠的創建方法有2個過載,如下所示:

  • AbstractNode * create(AbstractNode :: TYPE)const;
  • AbstractNode * create(AbstractNode :: TYPE,Vector3)const;

在工廠裏,我有一個會照顧創建過程(基於節點的類型)的私有方法在這裏是創建一個球的方法有兩種:

  • 是AbstractNode * createBall ()const;
  • AbstractNode * createBall(Vector3)const;

最後這裏是兩個地圖,其中我存儲所有的函數指針。這些地圖將在調用正確的方法創建(當然,如果可能的)

typedef AbstractNode* (*Functor)(void); 
typedef AbstractNode* (*FunctorPosition)(Vector3); 

map<unsigned int, Functor> functors_; 
<unsigned int, FunctorPosition> functorsPosition_; 

重定向現在,我的問題是,這將是在兩個地圖添加函數指針的語法。

這是我最後一次嘗試,它不編譯並引發以下錯誤:

functors_.insert(make_pair(AbstractNode::NAME_BALL, &createBall)); 

所示的錯誤:事先

No instance of function template std::make_pair matches the argument list 
Argument types are (const unsigned int, <unkown-type>) 

謝謝!

+0

請注意,指向函數的指針和指向(非靜態)成員函數的指針是有區別的。請參見[parashift C++ FAQ](http://www.parashift.com/c++-faq/fnptr-vs-memfnptr-types.html) – dyp

+1

這與「std :: map」沒有任何關係。 –

回答

2

createBall是一個非靜態成員函數。指針 - 成員函數類型與指針 - 函數類型不同。

所以,&createBall的類型不是AbstractNode* (*)(void),這是AbstractNode* (Factory::*)(void)const,其中Factory是它出現在類的名稱。如果你想那麼一個指針到成員函數改變型Functor(並確保當你來打電話時,你有一個Factory的實例來調用它)。如果你想要一個指向函數的指針,那麼將createBall更改爲靜態成員函數。

此外,由於&createBall在稱爲createBall的兩個重載之間不明確,因此編譯器無法確定要創建的對的類型。一旦你的類型Functor正確的,你可以寫:

functors_.insert(make_pair(AbstractNode::NAME_BALL, (Functor)&createBall)); 
functorsPosition_.insert(make_pair(AbstractNode::NAME_BALL, (FunctorPosition)&createBall)); 

演員告訴這工作,你的意思是編譯器 - 這是一個特殊的例外,在C通常的規則++,一個子表達式的類型&createBall沒有按」 t取決於它出現的上下文。

我想你應該能夠避免與投:

functors_[AbstractNode::NAME_BALL] = &createBall; 

因爲指針賦值給一個重載函數同樣是一個特例。但我懶得檢查它。

+0

你是絕對正確的,我忘了宣佈函數爲靜態,生病給了一個嘗試 –

+0

@DanyKhalife:你也需要演員,特殊規則不會讓編譯器從哪種類型對'insert'需要,到'make_pair'應該有的模板參數。 –

+0

C風格的演員陣容真的讓我發癢......: -/ –