c++模板元编程2

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>
{

};//#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);
};

//...接受任一多参数

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

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














你可能感兴趣的:(编程,C++,boost)