<<C++primer>>函数模板与类模板相关知识点整理

1.类型萃取的原理

类型萃取利用模板形参的推演方式使得类型去掉了引用性质:

cpp 复制代码
//消除引用,保留原始特性  //类型萃取
/// </summary>
/// <param name="it"></param>
template<class _Ty>
struct my_remove_reference
{
	my_remove_reference()
	{
		int x = 10;
		_Ty Y = 10; 
	}
};
template<class _Ty>
struct my_remove_reference<_Ty&>
{
	my_remove_reference()
	{
		int x = 10;
		_Ty Y = 10;
	}
};
template<class _Ty>
struct my_remove_reference<_Ty&&>
{
	my_remove_reference()
	{
		int x = 10;
		_Ty Y = 10;
	}
	};

int main()
{
	my_remove_reference<int>i;
	my_remove_reference<int&>ilr;
	my_remove_reference<const int&>cilr;//调用struct my_remove_reference<_Ty&>
	my_remove_reference<int&&>rll; //调用struct my_remove_reference<_Ty&&>
	//student<int&> s1;
//	cout << s1.X << endl;
}
#endif

使用示例1:acs作为了a的引用。

cpp 复制代码
/*类型转化示例,头文件type_traits*/
//1 转换成引用型别
int  main()
{
	int a = 10;
	int& b = a;
	add_lvalue_reference<int>::type acs  = a;
	acs = 100;
	cout << a;
}

使用示例2:rm的类型是int 而非int&

cpp 复制代码
2 将引用转化为值类型
int main()
{
	int a = 10;
	int& ab = a;
	remove_reference<int&>::type rm = ab;
	std::cout<<typeid(rm).name();
	return 0;
}

2.在模板函数中,编译器无法确认返回类型,需要使用typename 告知其是类型

使用类的类型成员:为了知道模板函数中名字是否可以表示一个类型,用typename通知这是表示一个类型。

cpp 复制代码
#if 0
/*使用类的类型成员:为了知道模板函数中名字是否可以表示一个类型,用typename通知这是表示一个类型*/
//此为返回一个容器成员类型的函数
template<class T>
typename T::value_type fun(const T& x)
{
	cout << "T" << typeid(T).name() << "\n";
	cout <<"typeid(T::value_type).name()"<< typeid(T::value_type).name() << "\n";
	if (!x.empty())
	{
		return x.back();
	}
	else {
		return typename T::value_type();
	}
	//std::cout << x << " ,   T::value_type :" << typeid(T).name() << "\n";
	//return typename T:: value_type();
}

int main()
{

	int a = 10;

	vector<int> vec;
	auto res1 = fun<vector<int>>(vec);
	cout << typeid(res1).name() << "\n";
	cout << res1;
	return 0;
}
#endif

T::value_type 表示为容器元素的类型。

注意:auto res1 = fun<vector<int>>(vec); 也可写成auto res1 = fun(vec);

一个是显示指定参数类型,一个是隐式的自动匹配对应的模板函数。

3.使用decltype关键字返回你想要返回的类型

在某些时候我们不想使用指定模板实参作为函数的返回值,而使用此关键字告诉编译器,返回类型和decltype括号中的类型相同。

示例:

cpp 复制代码
template<class It>
auto fnc1(It beg, It end) ->decltype(*beg)
{
	return *beg;
}


int main()
{
	string st = "111";
	vector<string>arr={ "111" };
	auto &res = fnc1(arr.begin(), arr.end());
	cout << typeid(res).name() << " ";
	cout << res;
	return 0;
}

移除引用型别

cpp 复制代码
template<class It>
auto fnc(It beg, It end) ->//decltype(*beg)
typename remove_reference<decltype(*beg)> ::type
{
	cout<<typeid(*beg).name()<<"             ";
	//*beg = 100;
	return *beg;
}

int main()
{
	string st = "111";
	vector<string>arr={ "111" };
	auto res = fnc(arr.begin(), arr.end());
	cout << typeid(res).name() << " ";
	cout << res;
	return 0;
}

注意,此函数调用时的返回类型要求是非引用类型,所以在函数中做了移除引用型别的处理。

4.引用折叠和理解move

5.模板参数与作用域

6.类模板的成员模板

7,显示实例化

相关推荐
IvanCodes4 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
aramae5 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
qq_2518364578 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
郑州光合科技余经理9 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手9 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
qq_199886879 小时前
第8板块·第2节:统一内存的高级特性与性能调优
c++·人工智能·gpu算力·cuda
+VX:Fegn08959 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
阿里嘎多学长10 小时前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
2401_8390805410 小时前
C++常见八股
数据结构·c++·算法
qq_1998868710 小时前
第6板块 第2节 CUDA运行时API与驱动API 核心笔记
c++·人工智能·gpu算力