我有两个班,DynamicCollectionDictionaryDictionaryDynamicCollection继承,并且两个类都是模板。看起来像这样:

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 );


我收到一条错误消息,指出找不到匹配的声明(这对我来说很有意义)。

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

最佳答案

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

话虽这么说,尽管您可以使其编译,但是您仍然具有循环依赖性,这通常是设计上的气味。有多种技术可以消除循环依赖关系,最常见的技术是拆分为更多组件并将一部分代码移到更高/更低的级别。在这种特殊情况下,您可能要考虑使GroupByDynamicCollection之外的免费函数或实用程序,这样依赖关系就会变成:

    GroupBy -- free function or component
       v
   Dictionary
       v
DynamicCollection


如果没有对设计的完整了解,甚至无法解决问题,就很难说这是否是最佳解决方案,但是无论如何,通用方法都应该起作用。

09-25 20:57