#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
template<template<typename, typename> class T, typename T_T, typename T_U>
void func(T<T_T, T_U> t) {
typename decltype(t)::iterator t_it;
typename T<T_T, T_U>::iterator t_it2;
std::cout << "* Passed as: "
<< typeid(T<T_T, T_U>).name() << '\n'
<< "** With element type: "
<< typeid(T_T).name() << '\n'
<< "** And allocator type: "
<< typeid(T_U).name() << '\n'
<< "** And iterator type: "
<< typeid(t_it).name() << '\n'
<< " (" << typeid(t_it2).name() << ")"
<< std::endl;
}
template<typename T>
void cnuf(T t) {
std::cout << "* And as: "
<< typeid(T).name() << '\n'
<< "* With iterator type: "
<< typeid(typename T::iterator).name()
<< std::endl;
}
int main() {
std::vector<int> vIntA;
std::vector<int, std::allocator<std::string>> vStrA;
decltype(vIntA)::iterator vII;
decltype(vStrA)::iterator vSI;
std::cout << "First vector: \n"
<< "* " << typeid(decltype(vIntA)).name() << '\n'
<< "* Allocator: "
<< typeid(decltype(vIntA)::allocator_type).name() << '\n'
<< "* Iterator: "
<< typeid(vII).name() << std::endl;
func(vIntA);
cnuf(vIntA);
std::cout << std::endl;
std::cout << "Second vector: \n"
<< "* " << typeid(decltype(vStrA)).name() << '\n'
<< "* Allocator: "
<< typeid(decltype(vStrA)::allocator_type).name() << '\n'
<< "* Iterator: "
<< typeid(vSI).name() << std::endl;
func(vStrA);
cnuf(vStrA);
}