Ассоциативный контейнер как параметр шаблона функции - PullRequest
2 голосов
/ 30 сентября 2011

Я хотел бы знать, как написать функцию, которая может принимать в качестве параметра ассоциативный контейнер, который сам принимает два или более параметров шаблона. Например, если я хочу написать функцию, которая работает для std :: map, я мог бы написать что-то вроде того, что показано ниже.

template <class Map, class Key, class Value, class Compare, class Allocator>
void foo(Map<Key, Value, Compare, Allocator>& map);

Однако, это не будет работать для boost :: unordered_map, так как boost :: unordered_map принимает пять параметров шаблона. Я мог бы принять карту в качестве единственного параметра шаблона и использовать признаки, которые она должна поддерживать, чтобы позднее вывести тип ключа и значения, но для вложенных карт код становится очень многословным и сложным в обслуживании. Есть ли более простой способ написать такую ​​функцию, но при этом она работает для любого ассоциативного контейнера, который принимает любое количество параметров шаблона больше или равно двум?

Обратите внимание, что принятия итераторов вместо контейнеров в качестве параметров будет недостаточно, потому что мне нужно больше информации о контейнере, с которым работает итератор, чем то, что может предоставить итератор.

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 30 сентября 2011

Почему бы просто не использовать простой подход с одним параметром шаблона:

template <typename C> void foo(const C & container)
{
  typedef typename C::key_type key_type;
  typedef typename C::mapped_type mapped_type;

  // etc.
}

Вы можете добавить некоторые типографские наборы для проверки типов элементов, если вам нужны дополнительные проверки того, что эти типы элементов существуют, но это может не дать никаких дополнительных преимуществ.

В качестве альтернативы, вы можете выполнить общее сопоставление с образцом, но только с классами, а не с функциями:

 template <typename> struct AtLeastTwo;

 template <typename K, typename V, typename ...Args>
 struct AtLeastTo<K, V, Args...>
 {
   // now have types K and V
 };

 typedef std::unordered_map<int, Foo, MyHash> map_type;
 AtLeastTwo<map_type> m;
 // ...
0 голосов
/ 30 сентября 2011

Тип не передает информацию о том, является ли он ассоциативной последовательностью, таково семантическое значение.Если вы не хотите поддерживать все виды ассоциативных последовательностей в соответствии со стандартным интерфейсом, вам лучше всего использовать один параметр шаблона и использовать черты для анализа его типа ключ / значение и т. Д.

...