我有两个课程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 );
我收到一条错误消息,说它无法找到匹配的声明(某种对我来说有意义)。
所以我的问题是:如何正确声明和定义此方法?
答案 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 )