Да, с аргументами шаблона шаблона:
template <template <typename, typename> class M, typename K, typename V>
void Foo(M<K, V> & container)
{
// ...
};
Обратите внимание, что это никогда не будет соответствовать ни одному контейнеру реального слова, потому что у них гораздо больше аргументов шаблона.Лучше с variadics:
template <template <typename, typename, typename...> class M, typename K, typename V, typename ...Args>
void Foo(M<K, V, Args...> & container)
{
// ...
};
Если variadics не вариант, вы можете использовать немного обертывания самостоятельно:
template <typename Container> void FooImpl(Container &);
template <template <typename, typename> class M,
typename K, typename V>
void Foo(M<K,V> & c) { FooImpl(c); }
template <template <typename, typename, typename> class M,
typename K, typename V, typename A1>
void Foo(M<K,V,A1> & c) { FooImpl(c); }
template <template <typename, typename, typename, typename> class M,
typename K, typename V, typename A1, typename A2>
void Foo(M<K,V,A1,A2> & c) { FooImpl(c); }
// etc.
Для справки std::unordered_map
принимает пять параметров шаблонаключ, значение, хеш-функтор, предикат равенства, распределитель).Boost bimap
может потребовать еще больше.
Злоупотребление этой последней конструкцией можно предотвратить, сделав функции статическими членами класса-оболочки и сделав реализацию закрытой, и предоставив одну вспомогательную функцию-метод доступа.