我有两个班,DynamicCollection
和Dictionary
。 Dictionary
从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 );
我收到一条错误消息,指出找不到匹配的声明(这对我来说很有意义)。
所以我的问题是:如何正确声明和定义此方法?
最佳答案
从语言的角度来看,可以在定义Dictionary
类型之前先声明DynamicCollection
模板,然后在定义Dictionary
之前先定义DynamicCollection<ValueType>::GroupBy
进行编译。
话虽这么说,尽管您可以使其编译,但是您仍然具有循环依赖性,这通常是设计上的气味。有多种技术可以消除循环依赖关系,最常见的技术是拆分为更多组件并将一部分代码移到更高/更低的级别。在这种特殊情况下,您可能要考虑使GroupBy
是DynamicCollection
之外的免费函数或实用程序,这样依赖关系就会变成:
GroupBy -- free function or component
v
Dictionary
v
DynamicCollection
如果没有对设计的完整了解,甚至无法解决问题,就很难说这是否是最佳解决方案,但是无论如何,通用方法都应该起作用。