c++模板元編程第二章練習題
2-0. 編寫一個一元元函數add_const_ref
const&。編寫一個程序來測試你的元函數。提示:可以使用boost::is_same來測試結果。
這個比較簡單:
template測試代碼:struct add_const_ref { typedef T const& type; }; template struct add_const_ref { typedef T& type; };
void fun_add_const_ref() { typedef const int Cint; typedef const int& CRint; typedef int& Rint; if (boost::is_same::type>::value) { std::cout << "true\n\n"; } else { std::cout << "false\n\n"; } if (boost::is_same ::type>::value) { std::cout << "true\n\n"; } { std::cout << "false\n\n"; } }
這個比較復雜:
分為4步解決
1. 首先判斷c中是否含有類型x
2.如果有替換
3沒有就返回元類型
4考慮一些模板特化
template#1判斷兩個類型時候為同一個類型 如果是返回true,否則返回falsestruct is_same: boost::mpl::bool_ { };//#1 template struct is_same : boost::mpl::bool_ { };//#1 template struct replace_type_imp;//#2 template struct replace_type { static bool const value = is_same ::value;//#3 typedef typename replace_type_imp ::type type;//#4 };
#2replace_type的具體實現,包含一個特化情況
#3返回時候相同value記錄返回結果
#4根據vlaue的值返回類型
下面是一般類型的實現:
////特化void //TC:void const*, TX:void const templatestruct replace_type_imp { typedef typename replace_type ::type type(); }; //特化TC* //TC:int const*, TX:int const template struct replace_type_imp { typedef typename replace_type ::type* type; }; //特化TC& //TC::int const&, TX:int const template struct replace_type_imp { typedef typename replace_type ::type& type; }; //特化TC[] //TC::int const[], TX:int const template struct replace_type_imp { typedef typename replace_type ::type type[]; }; //特化TC[N] //TC::int const[N], TX:int const template struct replace_type_imp { typedef typename replace_type ::type type[N]; };
//接受一個參數 //TC:: char* (*)(char*), TX: char*, TY: int templatestruct replace_type_imp { typedef typename replace_type ::type type(typename replace_type::type);//#1 //#1處怎麼能定義成一個 函數指針 }; //接受兩個參數 //TC:: char* (*)(char*, const char* ), TX: char*, TY:: int template struct replace_type_imp { typedef typename replace_type ::type type(typename replace_type::type, typename replace_type::type); }; //接受三個函數 template struct replace_type_imp { typedef typename replace_type ::type type(typename replace_type::type, typename replace_type::type, typename replace_type::type); }; //...接受任一多參數
templatestruct replace_type_imp { 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::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type ::type v4; if (is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type ::type v5; if (is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; typedef replace_type ::type v6; if (is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; if (boost::is_same ::value) std::cout << "same\n\n"; else std::cout << "false\n\n" << std::endl; }
這個題沒有理解題意,不會做,囧~~~~~~
2-3. 使用type traits
設施實現一個type_descriptor類模板,當被流化(streamed)時,其實例打印
其模板參數的類型:
std::cout<
std::cout<
你可以假定type_descriptor的模板參數局限於
根據以下四種整型構建的復合類型:char、short int、int以及long int。
這個題比較簡單,不說了直接貼代碼:
template測試代碼:struct get_description { static std::string value; operator const char*() { return value.c_str(); } }; template std::string get_description ::value = "can not deduce the type"; template<> std::string get_description ::value = "int"; template<> std::string get_description ::value = "char"; template<> std::string get_description ::value = "short"; template<> std::string get_description ::value = "long"; template<> std::string get_description ::value = "float"; template<> std::string get_description ::value = "double"; template struct get_description { operator const char*() { static std::string ret = get_description (); ret += " const"; return ret.c_str(); } }; template struct get_description { operator const char*() { static std::string ret = get_description (); ret += " *"; return ret.c_str(); } }; template struct get_description { operator const char* () { static std::string ret = get_description (); ret += " &"; return ret.c_str(); } };
void fun_type_descriptor() { std::cout << get_description() << std::endl; std::cout << get_description ()<< std::endl; //std::cout << get_description ()<< std::endl; }
這個題也比較簡單,直接上代碼:
templatestruct get_description { static std::string value; operator const char*() { return value.c_str(); } }; template std::string get_description ::value = "can not deduce the type"; template<> std::string get_description ::value = "int"; template<> std::string get_description ::value = "char"; template<> std::string get_description ::value = "short"; template<> std::string get_description ::value = "long"; template<> std::string get_description ::value = "float"; template<> std::string get_description ::value = "double"; template struct get_description { operator const char*() { static std::string ret = get_description (); ret += " const"; return ret.c_str(); } }; template struct get_description { operator const char*() { static std::string ret = get_description (); ret += " volatile"; return ret.c_str(); } }; template struct get_description { operator const char*() { static std::string ret = "pointer to "; ret += get_description (); return ret.c_str(); } }; template struct get_description { operator const char* () { static std::string ret = "reference to "; ret += get_description (); return ret.c_str(); } }; template struct get_description { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "array of "; ret += get_description (); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template struct get_description { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "array of "; ret += get_description (); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template struct get_description { operator const char* () { static std::string ret = "pointer to function returning "; ret += get_description (); return ret.c_str(); } }; template struct get_description { operator const char* () { static std::string ret = "this is a pointer function with "; ret += get_description(); ret += " and it pointer to function returning "; ret += get_description (); return ret.c_str(); } }; template struct get_description { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "pointer to function with "; ret += get_description(); ret += " returning "; ret += get_description (); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } }; template struct get_description { operator const char* () { std::cout << typeid(T).name() << "\n"; static std::string ret = "this is a pointer function with "; ret += get_description(); ret += " and it pointer to function with "; ret += get_description(); ret += " returning "; ret += get_description (); std::cout << typeid(T).name() << "\n"; return ret.c_str(); } };
void fun_text_descriptor() { //std::cout << get_description() << std::endl; typedef int (*FunPoint[10])(char*); std::cout << get_description ()<< std::endl; std::cout << get_description () << std::endl; }