c++模板元编程2

来源:互联网 发布:linux 进程管理 编辑:程序博客网 时间:2024/04/30 13:07

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";}}



2-1. 编写一个三元元函数replace_type<c,x,y>,它接收一个任意的复合类型c作为其第一个参数,
并将c中出现的所有type x替换为y:
typedef replace_type< void*, void, int >::type t1; // int*
typedef replace_type<
int const*[10]
, int const
, long
>::type t2; // long* [10]
typedef replace_type<
char& (*)(char&)
, char&
, long&
>::type t3; // long& (*)(long&)
你可以将所操作的函数类型限制为具有少于两个参数的函数。

这个比较复杂:

分为4步解决

1. 首先判断c中是否含有类型x

2.如果有替换

3没有就返回元类型

4考虑一些模板特化

template<typename U, typename T>struct is_same: boost::mpl::bool_<false>{};//#1template<typename T>struct is_same<T, T> : boost::mpl::bool_<true>{};//#1template<typename TC, typename TX, typename TY, bool same>struct replace_type_imp;//#2template<typename TC, typename TX, typename TY> struct replace_type{static bool const value = is_same<TC, TX>::value;//#3typedef 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 consttemplate<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 consttemplate<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 consttemplate<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 consttemplate<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 consttemplate<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: inttemplate<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:: inttemplate<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);};//...接受任一多参数

value 为true:

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-2. boost::polymorphic_downcast
函数模板
实现一个带检查版本的static_cast,用于将指向多态
对象的指针向下转型:
template <class Target, class Source>inline Target polymorphic_downcast(Source* x)
{
assert( dynamic_cast<Target>(x) == x );
return static_cast<Target>(x);
}
在发行版的软件中,assertion消失并且polymorphic_downcast可以和简单的static_cast一样高效。使用该type traits设施来编写一个模板实现品,使其既可接收指针参数也可接收引用参数:
struct A { virtual ~A() {} };
struct B : A {};
B b;
A* a_ptr = &b;B* b_ptr = polymorphic_downcast<B*>(a_ptr);A& a_ref = b;
B& b_ref = polymorphic_downcast<B&>(a_ref);

这个题没有理解题意,不会做,囧~~~~~~


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;}


2-5. 修改练习2-3中的type_descriptor
模板,使其输出type的伪英语描述,就像cdecl程序的
explain命令所做的那样:
//打印“array of pointer to function returning pointer to char”
std::cout << type_descriptor< char *(*[])() >();

这个题也比较简单,直接上代码:

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;}

好了就做了这几个题!!!!














0 0
原创粉丝点击