2014-04-26 77 views
0

我修改模板A *搜索現在有下面的類(部分):模板依賴的typedef

template <typename TNode, typename THeuristic> 
class AStar 
{ 
public: 
    // Typedefs. 
    typedef d_ary_heap<TNode*, boost::heap::compare<NodeCompare<TNode>>, boost::heap::arity<4>, boost::heap::mutable_<true>> PriorityQueueType; 

    //... 
} 

到現在爲止,我沒有想到templatizing啓發式參數,所以Node類定義如下:

template <typename T = float> 
class Node 
{ 
public: 
    // Typedefs: 
    typedef typename AStar<Node>::PriorityQueueType::handle_type HeapHandle; 

    //... 
} 

但現在因爲AStar需要第二個模板paremeter爲啓發式的typedef這裏給出了一個編譯錯誤:typedef typename AStar<Node ??>...。是否可以在保持自由指定AStar類中的啓發式的同時以某種方式進行此項工作?

+0

我可能會誤解你的問題,但不會給出默認的'THeuristic'(你已經知道該怎麼做 - 你在Node中使用它)就足夠了嗎? – hvd

+0

但是,如果我使用不同於默認的啓發式啓發式,那麼它會工作嗎? 'HeapHandle'與正確的類型不同,不是嗎? –

+0

'PriorityQueueType' typedef不依賴於'THeuristic'模板參數,因此它爲所有可能的'THeuristic'提供相同的類型。 – hvd

回答

3

你可以以不同的因素你的代碼,並保持啓發式無關部分分開:

namespace detail 
{ 
    template <typename T> 
    struct AStarHeap 
    { 
     using QueueType = /* ... */; 
     using HandleType = QueueType::handle_type; 
     // ... 
    }; 
} 

template <typename Node, typename Heur> 
struct AStar : detail::AStarHeap<Node> 
{ 
    // ... 
}; 

template <typename T> 
struct Node 
{ 
    using HeapHandle = typename detail::AStarHeap<T>::HandleType; 
    // ... 
}; 
+0

+1,我發現實際上我對這個問題的評論會導致與你的回答非常相似(但是已經分開發布) – hvd

+0

這就是我所做的,或多或少。請注意,'handle_type'是一個依賴名稱,所以在我的情況下,我不得不將該行修改爲'使用HandleType = typename QueueType :: handle_type'。 –

2

返工從我對這個問題的評論了一下,這裏就是我可能會做它:

template <typename TNode, typename THeuristic = void> 
class AStar; 

template <typename TNode> 
class AStar<TNode> 
{ 
    // put everything that does not depend on THeuristic here 
}; 

template <typename TNode, typename THeuristic> 
class AStar : public AStar<TNode> 
{ 
    // put everything that does depend on THeuristic here 
}; 

現在看看它,這與Kerrek SB的答案有很多相同的處理方法,但其優點是,只要不嘗試執行任何需要的任何操作,您現有的使用AStar<TNode>的代碼就會繼續編譯10。

+0

謝謝。我也使用了你的建議:默認技巧像你說的那樣工作,但我更喜歡將責任分離爲兩個不同的類。 –