The problem here is that
template <class, class...> T
and
template <class, class, class...> TM
both correspond to any template classes that have at least two template parameters, as in both examples. One thing you can do is make the template parameter lists more specific, for example, for example:
template <class> struct Printer; template <template<typename, typename> class C, template <typename> class A, typename T> struct Printer< C<T, A<T>> > { ... }; template <template<typename, typename, typename, typename> class C, template <typename> class Comp, template <typename> class A, typename K, typename T> struct Printer< C<K, T, Comp<K>, A<std::pair<const K,T>>> > { ... };
You can see that it works for std :: vector and std :: map here: http://coliru.stacked-crooked.com/a/7f6b8546b1ab5ba9
Another possibility is to use SFINAE (in fact, I would recommend using it in both scenarios):
template<template<class, class...> class T, class TV, class... TS, class = typename std::enable_if<std::is_same<T, std::vector>::value>::type> struct Printer<T<TV, TS...>> { ... }; template<template<class, class, class...> class TM, class TK, class TV, typename... TS, class = typename std::enable_if<std::is_same<T, std::map>::value>::type> struct Printer<TM<TK, TV, TS...>> { ... }
Edit: Oups, just read in the comments that you want to map something to "std :: vector" - sort of, and not specifically std :: vector. However, the first method should at least distinguish between std :: vector and std :: map. If you want to write algorithms for containers with different search methods, why not write your own functions for iterators and differentiate them?
Edit2: The code used to be terribly wrong. However, it works now.