2014-04-21 4 views
0

У меня есть два класса: 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 

Не имея полное представление о конструкции или даже проблем решить трудно сказать, является ли это лучшим решением, но общий подход должен работать независимо.

0

Как ни странно, приведенный ниже код решил мою проблему. Я отправляю объявление Dictionary в заголовок DynamicCollection и объявляю метод в классе, как обычно. Затем я определяю метод в заголовке Dictionary, используя приведенное ниже объявление, и все работает. Два объявления шаблона на одной строке. Интересно, почему и как это работает.

template <typename ValueType> template <typename Selector> 
Dictionary<Selector, ICollection<ValueType>*>* DynamicCollection<ValueType>::GroupBy(std::function<Selector(ValueType)> evaluator) 
Смежные вопросы