2011-05-31 153 views
1

我正在研究從遊戲AI通過示例書的工作代碼,並有一部分我不明白。我可以依靠模板類型嗎?

template <class node_type, class edge_type> 
class SparseGraph         
{ ... }; 

int SparseGraph<node_type, edge_type>::AddNode(node_type node) 
{ 
    if (node.Index() < (int)m_Nodes.size()) 
... 
}  

怎麼能node.Index()叫什麼名字?

也有類

class GraphNode 
{ 
public: 
... 
    int Index()const{return m_iIndex;} 
.... 
}; 

和圖形與此類

typedef SparseGraph<GraphNode, GraphEdge> NavGraph; 
NavGraph * m_pGraph; 

讓我明白了什麼node.Index()做創建,但 我怎麼能叫node.Index()雖然沒有保證node_typeGraphNode

如果node_type不是GraphNode

希望你能理解我的問題。

+3

我想你需要一本好書,告訴你模板是如何工作的。 「鴨子打字」是關鍵字。 – Xeo 2011-05-31 19:45:45

+1

@Xeo:如果您不想閱讀由熟悉動態編程語言的人撰寫的大量博客文章,請參閱「參數多態性」。 :-P – ildjarn 2011-05-31 20:00:17

+0

@ildjarn:但鴨子打字聽起來更好。 :( – Xeo 2011-05-31 20:46:35

回答

7

如果node_type不是GraphNode,那麼你的編譯器會打你並且拋出一個錯誤。但是,如果你的類依賴於Index函數,那麼你應該把它作爲一個需求來記錄,任何GraphNode的替代品都必須提供它,可能需要一些預期的語義。

+1

+1對於所有這些談話都有些貶低。:-) – 2011-05-31 19:44:33

+0

+1。 – phooji 2011-05-31 19:46:52

+0

好的,那麼爲此使用模板的目的是什麼?我可以用基類GraphNode和多態來做到,不是嗎? – relaxxx 2011-05-31 19:56:03

2

C++模板函數在使用時被實例化。即,當您指定時,它會粘貼您指定的類型,並且不會更早。此時,如果您指定的類型沒有Index成員函數,則編譯將失敗。

3

Duck typing

C++中還有一個很方便的功能叫做SFINAE(替換失敗不是錯誤),如果依賴於類型的表達式不能用特定的具體類型進行編譯,它將從被考慮的候選項中移除一個模板。

基於支持的操作(即Concepts)限制接受爲模板參數的類型的方法最初是爲C++ 0x計劃的,但由於委員會在其設計上存在分歧而被廢棄。您仍然可以在GCC的某些分支中找到早期實現,並且Boost也有一個概念庫。請參閱here

相關問題