模板类依赖性问题

时间:2014-04-21 15:15:17

标签: c++ templates dependencies

我有两个课程DynamicCollectionDictionaryDictionary继承自DynamicCollection,两个类都是模板。看起来像这样:

template <typename ValueType>
class DynamicCollection;

template <typename KeyType, typename ValueType>
class Dictionary : public DynamicCollection<KeyValuePair<KeyType, ValueType>>;

我遇到的问题是DynamicCollection需要一个方法GroupBy,其声明如下:

template <typename Selector>
Dictionary<Selector, ICollection<ValueType>*>* GroupBy( std::function<Selector(ValueType)> evaluator );

所以我遇到的问题是循环依赖,我不知道如何重写它以便它可以工作。我已经尝试在Dictionary标头中声明DynamicCollection,然后在Dictionary标头中定义方法,但后来我遇到了这种奇怪的情况:

template <typename Selector>
Dictionary<Selector, ICollection<ValueType>*>* DynamicCollection::GroupBy( std::function<Selector( ValueType )> evaluator );

但是,正如您所猜测的那样,DynamicCollection需要一个模板参数列表,并且函数对象的ValueType(以及返回中的ICollection)需要是来自ValueType声明的DynamicCollection。所以,这显然是错误的代码,但我觉得它会是这样的(如果我必须在Dictionary标题中定义它):

template <typename ValueType>
template <typename Selector>
Dictionary<Selector, ICollection<ValueType>*>* DynamicCollection<ValueType>::GroupBy( std::function<Selector( ValueType )> evaluator );

因为当我这样定义时:

template <typename ValueType, typename Selector>
Dictionary<Selector, ICollection<ValueType>*>* DynamicCollection<ValueType>::GroupBy( std::function<Selector( ValueType )> evaluator );

我收到一条错误消息,说它无法找到匹配的声明(某种对我来说有意义)。

所以我的问题是:如何正确声明和定义此方法

2 个答案:

答案 0 :(得分:1)

从语言的角度来看,您可以在定义Dictionary类型之前声明DynamicCollection模板,然后在定义Dictionary之前定义DynamicCollection<ValueType>::GroupBy来进行编译。 }

话虽如此,虽然你可以编译,但你仍然有一个循环依赖,这通常是设计上的气味。有不同的技术可以消除循环依赖关系,最常见的是拆分成更多组件并将部分代码移动到更高/更低的级别。在这种特殊情况下,您可能需要考虑将GroupBy设置为DynamicCollection之外的自由函数或实用程序,这样依赖关系就会变成:

    GroupBy -- free function or component
       v
   Dictionary
       v
DynamicCollection

如果没有完整的设计视图,甚至无法解决问题,很难说这是否是最佳解决方案,但一般方法无论如何都应该有效。

答案 1 :(得分:0)

奇怪的是,下面的代码解决了我的问题。我转发在Dictionary标头中声明此DynamicCollection,并按照通常的方式在类中声明方法。然后我使用以下声明在Dictionary标题中定义方法,并且工作正常。一行上有两个模板声明。我想知道为什么/如何运作。

template <typename ValueType> template <typename Selector>
Dictionary<Selector, ICollection<ValueType>*>* DynamicCollection<ValueType>::GroupBy( std::function<Selector( ValueType )> evaluator )