#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <valarray>
#include <string>

template <template <typename ...> class P, typename ... Args>
void f(const P<Args...> &p) { std::cout << sizeof...(Args) << " parameters! " << __PRETTY_FUNCTION__ << '\n';  }

template <template <typename ...> class P, typename ... Args>
struct c
{
	using type = P<Args...>; 
	const std::size_t count = sizeof...(Args);

	void f(const type &t) { std::cout << sizeof...(Args) << " parameters! " << __PRETTY_FUNCTION__ << '\n';  }
};

template <template <typename, typename> class P, typename A, typename B>
struct c<P, A, B> 
{
	using type = P<A, B>; 

	void f(const type &t) { std::cout << "Specialized --> " << __PRETTY_FUNCTION__ << '\n';  }
};

int main()
{
	f(std::valarray<int>{});
	f(std::pair<char, char>{});
	f(std::vector<double>{});
	f(std::set<float>{});
	f(std::map<int, int>{});
	std::cout << '\n';
	c<std::valarray, int> c_valarray_int;
	c<std::pair, int, char> c_pair_int_char;
	c<std::vector, int, std::allocator<int>> c_vector_int;
	c<std::map, int, int> c_map_int_int;

	c_valarray_int.f({});
	c_pair_int_char.f({});
	c_vector_int.f({});
	c_map_int_int.f({});

	return 0;
}