9-3 理解模板类型推断、查看类型推断结果(未归类知识点)

004理解模板类型参数_查看类型推断结果

#include<iostream>
#include<cstdlib>
#include <boost/type_index.hpp>

using namespace std;

//显示参数类型,这里不研究boost库
template<typename T>
//void myFunction01(T&tem)//T是类型模板参数,T是有类型的,tem是形参,tem也是有类型的
void myFunction01(const T &tem)
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}

//2.1指针或者引用类型
template<typename T>
void myFunction02( T &tem)//tem是引用
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}

template<typename T>
void myFunction03( const T &tem)//形参是常量引用
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}

template<typename T>
void myFunction04( T *tem)//形参是指针类型
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}

template<typename T>
void myFunction05(T &&tem)//形参是万能引用类型
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}


template<typename T>
void myFunction06(T tem)//形参是万能引用类型
{
	using boost::typeindex::type_id_with_cvr;
	cout << "T type=" << type_id_with_cvr<T>().pretty_name() << endl;//显示T类型
	cout << "tem type=" << type_id_with_cvr<decltype(tem)>().pretty_name() << endl;//显示T类型

}

void tesFunction()
{
	;
}
int main(void)
{
	//(2)void myFunction01(const T&tem)
	myFunction01(100);
	/*
	 * T type=int
	 * tem type=int const &
	 */
	
	//2.1
	int i = 18;	//int
	const int j = i;	//const int
	const int&k = i;	//const int&类型
	cout << "-----" << endl;
	myFunction02(i);
	myFunction02(j);
	myFunction02(k);
	/*
	 *	T type=int
		tem type=int &
		T type=int const
		tem type=int const &
		T type=int const
		tem type=int const &
	1.如果实参是引用类型,则引用类型会被忽略掉,T不会被推到为引用类型。
	2.当我们向引用类型的形参tem传递const类型实参时,形参就会成为const&
		实参的const属性会成为类型模板参数的推导的类型的组成部分,
		也就是说,实参的const属性会传递。在函数中修改不了原来带const属性的实参。
	
	 */

	//形参是常量引用
	cout << "*******" << endl;
	myFunction03(i);
	myFunction03(j);
	myFunction03(k);
	/*
	 *  T type=int
		tem type=int const &
		T type=int
		tem type=int const &
		T type=int
		tem type=int const &

	1.如果实参是引用类型,则引用类型会被忽略掉,T不会被推到为引用类型。
	2.对于有const属性的实参,推导后T中的const属性没有了,因为模板函数myFunction03的形参tem出现了const。实参const替换掉形参const
	
	 */

	//指针类型
	const int*pi = &i;
	cout << "&&&&&&&&&" << endl;
	myFunction04(&i);
	myFunction04(pi);
	/*
	 *  T type=int
		tem type=int *
		T type=int const
		tem type=int const *
	结论:如果tem形参中没有const,则实参中的const就会传递到T类型中去。如果形参中有const,则T类型中不会带const。
	
	 */

	//*	2.2万能引用--形式参数tem是一个万能引用类型T&&
	cout << "2.2------------------------" << endl;
	myFunction05(i);//左值
	myFunction05(j);//左值
	myFunction05(k);
	myFunction05(100);//传递过去右值
	/*
	T type=int &
	tem type=int &	//这里有引用折叠
	T type=int const &
	tem type=int const &
	T type=int const &
	tem type=int const &
	T type=int
	tem type=int &&
	 */


	//2.3传值方式 如果形式参数tem是常规的传值方式传递
	cout << "2.3------------------------" << endl;
	myFunction06(i);
	myFunction06(j);
	myFunction06(k);
	/*
	 *  T type=int
		tem type=int
		T type=int
		tem type=int
		T type=int
		tem type=int
	const属性没有传递进去,因为形式参数是一个新副本。怎么传递进去const属性???-->传递指针进去
	 */
	char myStr[] = "jisuanjizuchengyhuanli";
	const char*const point = myStr;//第一个const修饰内存空间,第二个表示指针的指向不能改变
	cout << "jjjjjjjjjjjjjjjj" << endl;
	myFunction06(point);
	/*
	 T type=char const *
	 tem type=char const *
	传递const char*或者const char[]第一个const没有了,第二个const保留。
	 */

	//2.4数组做实参
	const char mystr02[] = "jisuanjizuchegnaun";
	cout << "22222222222222222222222" << endl;

	myFunction06(mystr02);
	myFunction02(mystr02);//调引用--推导成数组
	/*
	T type=char const *
	tem type=char const *
	T type=char const [19]
	tem type=char const (&)[19]//代表数组的引用
	*/

	//	2.5函数名做实参,函数名相当于函数首地址,可以赋值给一个函数指针
	cout << "6666666666666" << endl;
	myFunction06(tesFunction);

	myFunction02(tesFunction);//引用
	/*
	T type=void (__cdecl*)(void)//函数指针类型
	tem type=void (__cdecl*)(void)
	T type=void __cdecl(void)//函数指针引用
	tem type=void (__cdecl&)(void)
	 */

	
	cout << "helloWorld" << endl;
	system("pause");
	return 0;
}

/*
*(1)如何查看类型推断结果
*	推断有时候叫做推导,在现代c++中,经常涉及到推断,如auto等。这里主要讲解模板类型推断的知识。
*	模拟编译器来推断一个模板参数和普通参数的类型。
*	这里要验证我们推断出的类型和编译器推断出来的类型是否一致。--学习类型推断的原因?
*	我们为了学习类型推断相关知识,有必要知道编译器推断出来的“模板参数类型”以及“普通参数类型”的protype
*
*	通过“查看编译器类型推断的结果”这个手段来学习并掌握c++类型推断的规则。要求掌握C++类型推断结果,
*	而不是依赖什么手段去查看编译器个我们推断出来的结果。
*
*	使用boost库,把编译器给我们推断出来的类型信息打印出来。
*		1.访问官网https://www.boost.org/ 下载boost库
*		2.点击右侧Version History可以下载到1.68.0版本
*		3.将文件解压到一个文件夹中,本例中boost_1_68_0,
*		4.右键项目--“属性”--“vc++目录”--“包含目录”中将解压的路径添加上
*	这里使用nuget安装,右键项目 --“管理NuGet安装包”,搜索boost安装包
*	
*(2)理解模板类型推断
*	2.1指针或者引用类型
*			如果tem类型是个指针或者引用,但是不是万能引用
*	2.2万能引用--形式参数tem是一个万能引用类型T&&
*
*	2.3传值方式
*
*	2.4数组做实参
*		数组名代表数组的首地址
*	2.5函数名做实参,函数名相当于函数首地址,可以赋值给一个函数指针
*(3)总结:
*	1.推断中,引用类型实参的引用类型等于不存在
*	2.万能引用中,实参为右值和左值,推断出来的结果不同
*	3.按值传递的实参,传递给形参时const属性不起作用,则传递过去指针可能起作用。
*	4.数组或者函数类型在推断中被看作指针,除非函数模板的形参是个引用。
*/

猜你喜欢

转载自blog.csdn.net/qq_39885372/article/details/107573908
9-3