2014-04-26 59 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

谢谢。我也使用了你的建议:默认技巧像你说的那样工作,但我更喜欢将责任分离为两个不同的类。 –