学习模板编程,做练习2-5: #include <cstdio> #include <iostream> #include <string> using namespace std; template<class T> class type_descriptor; template<> class type_descriptor<void> { public: static string str() { return "void"; } }; template<> class type_descriptor<bool> { public: static string str() { return "bool"; } }; template<> class type_descriptor<char> { public: static string str() { return "char"; } }; template<> class type_descriptor<signed char> { public: static string str() { return "signed char"; } }; template<> class type_descriptor<unsigned char> { public: static string str() { return "unsigned char"; } }; template<> class type_descriptor<short> { public: static string str() { return "short"; } }; template<> class type_descriptor<unsigned short> { public: static string str() { return "unsigned short"; } }; template<> class type_descriptor<int> { public: static string str() { return "int"; } }; template<> class type_descriptor<unsigned> { public: static string str() { return "unsigned"; } }; template<> class type_descriptor<long> { public: static string str() { return "unsigned long"; } }; template<> class type_descriptor<float> { public: static string str() { return "float"; } }; template<> class type_descriptor<double> { public: static string str() { return "double"; } }; template<> class type_descriptor<long double> { public: static string str() { return "long double"; } }; template<class T> class type_descriptor<const T> { public: static string str() { return "const " + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<volatile T> { public: static string str() { return "volatile " + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<const volatile T> { public: static string str() { return "const volatile " + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<T *> { public: static string str() { return "pointer to " + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<T &> { public: static string str() { return "reference to " + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<T []> { public: static string str() { return "array of " + type_descriptor<T>::str(); } }; template<class T, unsigned long N> class type_descriptor<T [N]> { public: static string str() { char buf[256]; sprintf(buf, "array of %lu ", N); return buf + type_descriptor<T>::str(); } }; template<class T> class type_descriptor<T ()> { public: static string str() { return "function returning " + type_descriptor<T>::str(); } }; template<class T, class A1> class type_descriptor<T (A1)> { public: static string str() { return "function returning " + type_descriptor<T>::str() + " taking an argument " + type_descriptor<A1>::str(); } }; template<class T, class A1, class A2> class type_descriptor<T (A1, A2)> { public: static string str() { return "function returning " + type_descriptor<T>::str() + " taking arguments " + type_descriptor<A1>::str() + " and " + type_descriptor<A2>::str(); } }; template<class T, class A1, class A2, class A3> class type_descriptor<T (A1, A2, A3)> { public: static string str() { return "function returning " + type_descriptor<T>::str() + " taking arguments " + type_descriptor<A1>::str() + ", " + type_descriptor<A2>::str() + " and " + type_descriptor<A3>::str(); } }; template<class T, class A1, class A2, class A3, class A4> class type_descriptor<T (A1, A2, A3, A4)> { public: static string str() { return "function returning " + type_descriptor<T>::str() + " taking arguments " + type_descriptor<A1>::str() + ", " + type_descriptor<A2>::str() + ", " + type_descriptor<A3>::str() + " and " + type_descriptor<A4>::str(); } }; template<class T> ostream &operator<<(ostream &ostr, const type_descriptor<T> &) { return ostr << type_descriptor<T>::str(); } int main() { cout << type_descriptor<const int (*[5]) (void *, bool &, bool, const char *)>() << endl; cout << type_descriptor<char *(*[])()>() << endl; return 0; }