程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++模板元編程2

c++模板元編程2

編輯:C++入門知識

c++模板元編程第二章練習題

2-0. 編寫一個一元元函數add_const_ref,如果T是一個引用類型,就返回T,否則返回T
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";
	}
}



2-1. 編寫一個三元元函數replace_type,它接收一個任意的復合類型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
struct 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
};
#1判斷兩個類型時候為同一個類型 如果是返回true,否則返回false

#2replace_type的具體實現,包含一個特化情況

#3返回時候相同value記錄返回結果

#4根據vlaue的值返回類型

下面是一般類型的實現:

////特化void
//TC:void const*, TX:void 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[]
//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
template
struct 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);
};

//...接受任一多參數

value 為true:

template
struct 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-2. boost::polymorphic_downcast
函數模板
實現一個帶檢查版本的static_cast,用於將指向多態
對象的指針向下轉型:
template inline Target polymorphic_downcast(Source* x)
{
assert( dynamic_cast(x) == x );
return static_cast(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(a_ptr);A& a_ref = b;
B& b_ref = polymorphic_downcast(a_ref);

這個題沒有理解題意,不會做,囧~~~~~~


2-3. 使用type traits
設施實現一個type_descriptor類模板,當被流化(streamed)時,其實例打印
其模板參數的類型:
std::cout<();//打印“char*”;
std::cout<();//打印“longconst*&”;
你可以假定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;
}


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

這個題也比較簡單,直接上代碼:

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

好了就做了這幾個題!!!!














  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved