c++模板元编程第二章练习题
2-0. 编写一个一元元函数add_const_ref<T>,如果T是一个引用类型,就返回T,否则返回T
const&。编写一个程序来测试你的元函数。提示:可以使用boost::is_same来测试结果。
这个比较简单:
template<typename T> struct add_const_ref { typedef T const& type; }; template<typename T> struct add_const_ref<T&> { typedef T& type; };测试代码:
void fun_add_const_ref() { typedef const int Cint; typedef const int& CRint; typedef int& Rint; if (boost::is_same<Rint, add_const_ref<Rint>::type>::value) { std::cout << "true\n\n"; } else { std::cout << "false\n\n"; } if (boost::is_same<CRint, add_const_ref<Cint>::type>::value) { std::cout << "true\n\n"; } { std::cout << "false\n\n"; } }
这个比较复杂:
分为4步解决
1. 首先判断c中是否含有类型x
2.如果有替换
3没有就返回元类型
4考虑一些模板特化
template<typename U, typename T> struct is_same: boost::mpl::bool_<false> { };//#1 template<typename T> struct is_same<T, T> : boost::mpl::bool_<true> { };//#1 template<typename TC, typename TX, typename TY, bool same> struct replace_type_imp;//#2 template<typename TC, typename TX, typename TY> struct replace_type { static bool const value = is_same<TC, TX>::value;//#3 typedef typename replace_type_imp<TC, TX, TY, value>::type type;//#4 };#1判断两个类型时候为同一个类型 如果是返回true,否则返回false
#2replace_type的具体实现,包含一个特化情况
#3返回时候相同value记录返回结果
#4根据vlaue的值返回类型
下面是一般类型的实现:
////特化void //TC:void const*, TX:void const template<typename TC, typename TX, typename TY> struct replace_type_imp<TC(), TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type(); }; //特化TC* //TC:int const*, TX:int const template<typename TC, typename TX, typename TY> struct replace_type_imp<TC*, TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type* type; }; //特化TC& //TC::int const&, TX:int const template<typename TC, typename TX, typename TY> struct replace_type_imp<TC&, TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type& type; }; //特化TC[] //TC::int const[], TX:int const template<typename TC, typename TX, typename TY> struct replace_type_imp<TC[], TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type[]; }; //特化TC[N] //TC::int const[N], TX:int const template<typename TC, typename TX, typename TY, int N> struct replace_type_imp<TC[N], TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type[N]; };
//接受一个参数 //TC:: char* (*)(char*), TX: char*, TY: int template<typename TC, typename TX, typename TY, typename Arg1> struct replace_type_imp<TC(Arg1), TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type(typename replace_type<Arg1, TX, TY>::type);//#1 //#1处怎么能定义成一个 函数指针 }; //接受两个参数 //TC:: char* (*)(char*, const char* ), TX: char*, TY:: int template<typename TC, typename TX, typename TY, typename Arg1, typename Arg2> struct replace_type_imp<TC(Arg1, Arg2), TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type(typename replace_type<Arg1, TX, TY>::type, typename replace_type<Arg2, TX, TY>::type); }; //接受三个函数 template<typename TC, typename TX, typename TY, typename Arg1, typename Arg2, typename Arg3> struct replace_type_imp<TC(Arg1, Arg2, Arg3), TX, TY, false> { typedef typename replace_type<TC, TX, TY>::type type(typename replace_type<Arg1, TX, TY>::type, typename replace_type<Arg2, TX, TY>::type, typename replace_type<Arg3, TX, TY>::type); }; //...接受任一多参数
template<typename TC, typename TX, typename TY> struct replace_type_imp<TC, TX, TY, true> { typedef TY type; };
void fun_is_same() { typedef char& (*FunPoint[])(char&); typedef char& Rchar; typedef const int v1; typedef const int v2; typedef int* v3; typedef int* (*IntPoint[])(int*); if (is_same<v1, v2>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same<v1, v2>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type<v1[10], v2, v3>::type v4; if (is_same<v3[10], v4>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same<v3[10], v4>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type<FunPoint, Rchar, v3>::type v5; if (is_same<IntPoint, v5>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same<IntPoint, v5>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type<v3 const, v3 const, v2>::type v6; if (is_same<v2, v6>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same<v2, v6>::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; }
这个题没有理解题意,不会做,囧~~~~~~
2-3. 使用type traits
设施实现一个type_descriptor类模板,当被流化(streamed)时,其实例打印
其模板参数的类型:
std::cout<<type_descriptor<char*>();//打印“char*”;
std::cout<<type_descriptor<long const*&>();//打印“longconst*&”;
你可以假定type_descriptor的模板参数局限于
根据以下四种整型构建的复合类型:char、short int、int以及long int。
这个题比较简单,不说了直接贴代码:
template<typename T> struct get_description { static std::string value; operator const char*() { return value.c_str(); } }; template<typename T> std::string get_description<T>::value = "can not deduce the type"; template<> std::string get_description<int>::value = "int"; template<> std::string get_description<char>::value = "char"; template<> std::string get_description<short>::value = "short"; template<> std::string get_description<long>::value = "long"; template<> std::string get_description<float>::value = "float"; template<> std::string get_description<double>::value = "double"; template<typename T> struct get_description<T const> { operator const char*() { static std::string ret = get_description<T>(); ret += " const"; return ret.c_str(); } }; template<typename T> struct get_description<T*> { operator const char*() { static std::string ret = get_description<T>(); ret += " *"; return ret.c_str(); } }; template<typename T> struct get_description<T&> { operator const char* () { static std::string ret = get_description<T>(); ret += " &"; return ret.c_str(); } };测试代码:
void fun_type_descriptor() { std::cout << get_description<int>() << std::endl; std::cout << get_description<long const *&>()<< std::endl; //std::cout << get_description<int&>()<< std::endl; }
这个题也比较简单,直接上代码:
template<typename T> struct get_description { static std::string value; operator const char*() { return value.c_str(); } }; template<typename T> std::string get_description<T>::value = "can not deduce the type"; template<> std::string get_description<int>::value = "int"; template<> std::string get_description<char>::value = "char"; template<> std::string get_description<short>::value = "short"; template<> std::string get_description<long>::value = "long"; template<> std::string get_description<float>::value = "float"; template<> std::string get_description<double>::value = "double"; template<typename T> struct get_description<T const> { operator const char*() { static std::string ret = get_description<T>(); ret += " const"; return ret.c_str(); } }; template<typename T> struct get_description<T volatile> { operator const char*() { static std::string ret = get_description<T>(); ret += " volatile"; return ret.c_str(); } }; template<typename T> struct get_description<T*> { operator const char*() { static std::string ret = "pointer to "; ret += get_description<T>(); return ret.c_str(); } }; template<typename T> struct get_description<T&> { operator const char* () { static std::string ret = "reference to "; ret += get_description<T>(); return ret.c_str(); } }; template<typename T> struct get_description<T[]> { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "array of "; ret += get_description<T>(); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template<typename T, int N> struct get_description<T[N]> { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "array of "; ret += get_description<T>(); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template<typename T> struct get_description<T(*)()> { operator const char* () { static std::string ret = "pointer to function returning "; ret += get_description<T>(); return ret.c_str(); } }; template<typename T, typename Arg1> struct get_description<T(*(Arg1))()> { operator const char* () { static std::string ret = "this is a pointer function with "; ret += get_description<Arg1>(); ret += " and it pointer to function returning "; ret += get_description<T>(); return ret.c_str(); } }; template<typename T, typename Arg1> struct get_description<T(*)(Arg1)> { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "pointer to function with "; ret += get_description<Arg1>(); ret += " returning "; ret += get_description<T>(); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template<typename T, typename Arg1, typename Arg2> struct get_description<T(*(Arg1))(Arg2)> { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "this is a pointer function with "; ret += get_description<Arg1>(); ret += " and it pointer to function with "; ret += get_description<Arg2>(); ret += " returning "; ret += get_description<T>(); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } };
void fun_text_descriptor() { //std::cout << get_description<int>() << std::endl; typedef int (*FunPoint[10])(char*); std::cout << get_description<FunPoint>()<< std::endl; std::cout << get_description<const char* (*(int&))(const float *&)>() << std::endl; }