C++基本用法实践之模板详解

 更新时间:2023年07月17日 11:24:53   作者:寡人正在Coding  
C++的模板是泛型编程思想的一种实现,模板不光支持函数模板,还有类模板等,本文主要来和大家聊聊C++中模板的相关用法,需要的可以参考一下

概述

C++的模板是泛型编程思想的一种实现。C++是强类型语言,处处强调类型。同样的加法运算,int和float的加法运算需定义两个函数(重载),而使用模板则可以只用一个函数(见下面示例)。

这类似我们面向对象所说的多态(定义加法运算,各个类型有不同的实现),所以是所谓静多态的一种实现方式,不同的是,模板在编译期展开生成int和float两个加法函数,如:

template<class T>
T add(T a, T b)
{
  return a + b;
}
int v1 = add<int>(1, 2);
// 不显式声明模板参数类型,编译器会试图推断
float v2 = add(1.5f, 2.5f);
/*
实际上编译器生成了两个函数
int add<int>(int a, int b)
float add<float>(float a, float b)
*/

模板不光支持函数模板,还有类模板等,思想是一样的(详情见下面例子)。

模板还有一些特性机制如:模板特化,SFINAE(substitution failure is not an error 替换而非错误),变长参数模板等,另外模板在元编程中也是十分重要的组成部分,我对元编程没有太多实践,读者有兴趣可以自行搜索。

用法举例

参考测试项目ModernCppTest/modrenc_template.cpp主要内容:

  • 函数模板&Lambda函数模板
  • 类模板
  • 别名模板
  • 变量模板
  • 值(枚举)作为模板参数(其实int类型也可以)
  • 模板特化
  • 变长参数模板
  • 模板函数的完美转发
#include "ModernCppTestHeader.h"
namespace n_template{
	template <class T>
	void template_func(T t)
	{
		LOG_VAR(t);
	}
	template <class T>
	class Number
	{
	public:
		T v;
		Number(T v) : v(v)
		{
			LOG_VAR(v);
		}
	};
	template <class T>
	constexpr T pi = T(3.1415926f);
	template <int INTVAL>
	void log_template_int_value()
	{
		LOG_VAR(INTVAL);
	}
	enum class EAnim : int {
		Other = 0,
		Cat = 1,
		Dog = 2,
	};
	template<EAnim Ty>
	class Anim
	{
	public:
		void Bark() { LOG("默认:动物叫"); }
	};
	template<>
	class Anim<EAnim::Dog>
	{
	public:
		void Bark() { LOG("狗:汪汪!"); }
	};
	template<>
	class Anim<EAnim::Cat>
	{
	public:
		void Bark() { LOG("猫:喵喵!"); }
	};
	// 注意递归基
	void log_values()
	{
		LOG("展开结束");
	}
	template<class T, class... ARGS>
	void log_values(T value, ARGS... args)
	{
		LOG(value);
		log_values(args...);
	}
	template<class T>
	void func_plus(T&& a)
	{
		auto v = a;
		LOG("func_plus v = " << a);
	}
	template<class T, class... ARGS>
	void func_plus(T&& a, T&& b, ARGS... args)
	{
		func_plus(a + b, std::forward<ARGS>(args)...);
	}
	template<class T>
	void func_mul(T&& a)
	{
		auto v = a;
		LOG("func_mul v = " << a);
	}
	template<class T, class... ARGS>
	void func_mul(T&& a, T&& b, ARGS... args)
	{
		func_mul(a + b, std::forward<ARGS>(args)...);
	}
	template <class... ARGS>
	void call_func(const std::string& name, ARGS&&... args)
	{
		if (name == "plus")
			func_plus(std::forward<ARGS>(args)...);
		else if (name == "mul")
			func_mul(std::forward<ARGS>(args)...);
		else
			LOG("Unknown function name: " << name);
	}
}
template<typename T>
using Num = n_template::Number<T>;
void template_test()
{
	LOG_FUNC();
	LOG_TAG(" 函数模板 ");
	{
		n_template::template_func(1);
		n_template::template_func(1.25f);
		LOG("Lambda 函数模板");
		auto f = []<class T> (T t) { LOG_VAR(t); };
		f(1);
		f(1.25f);
	}
	LOG_TAG("类模板");
	{
		n_template::Number(1);
		n_template::Number(1.25f);
	}
	LOG_TAG("别名模板");
	{
		Num<int>(1);
		Num<float>(1.25f);
	}
	LOG_TAG("变量模板");
	{
		auto v1 = n_template::pi<int>;
		auto v2 = n_template::pi<float>;
		LOG_VAR(v1);
		LOG_VAR(v2);
		n_template::log_template_int_value<10>();
		n_template::log_template_int_value<20>();
	}
	LOG_TAG("枚举变量模板&模板特化");
	{
		n_template::Anim<n_template::EAnim::Dog>().Bark();
		n_template::Anim<n_template::EAnim::Cat>().Bark();
		LOG("EAnim::Other 没有特化使用默认模板");
		n_template::Anim<n_template::EAnim::Other>().Bark();
	}
	LOG_TAG("变长参数模板");
	{
		n_template::log_values("jack", 10, 3.14f);
	}
	LOG_TAG("变长参数模板的完美转发");
	{
		n_template::call_func("plus", 1, 2, 3, 4);
		n_template::call_func("mul", 2, 3);
	}
}

到此这篇关于C++基本用法实践之模板详解的文章就介绍到这了,更多相关C++模板内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现获取邮件中的附件

    C++实现获取邮件中的附件

    这篇文章主要为大家详细介绍了如何通过C++实现获取邮件文件中的附件,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 使用C语言绘制柱形图的示例代码

    使用C语言绘制柱形图的示例代码

    常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图,这篇文章主要为大家介绍了C语言中绘制条形图和柱形图的方法,需要的可以参考下
    2024-02-02
  • C++最优二叉树哈夫曼树算法解析

    C++最优二叉树哈夫曼树算法解析

    这篇文章主要介绍了C++最优二叉树哈夫曼树算法解析,哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树,所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度,需要的朋友可以参考下
    2023-08-08
  • java string对象上的操作,常见的用法你知道吗

    java string对象上的操作,常见的用法你知道吗

    今天给大家带来的是关于Java的相关知识,文章围绕着Java String类用法展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-08-08
  • C++实现KFC点餐系统

    C++实现KFC点餐系统

    这篇文章主要为大家详细介绍了C++实现KFC点餐系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • C++中两种字符串定义方式和区别介绍

    C++中两种字符串定义方式和区别介绍

    大家好,本篇文章主要讲的是C++中两种字符串定义方式和区别介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C语言可变参数列表的用法与深度剖析

    C语言可变参数列表的用法与深度剖析

    这篇文章主要给大家介绍了关于C语言可变参数列表的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • c++实现发送http请求通过get方式获取网页源代码

    c++实现发送http请求通过get方式获取网页源代码

    这篇文章主要介绍了c++实现发送http请求,通过get方式获取网页源代码的示例,需要的朋友可以参考下
    2014-02-02
  • C语言编程const遇上指针分析

    C语言编程const遇上指针分析

    本篇文章是C语言编程篇,主要为大家介绍C语言编程中当Const遇上指针的分析讲解,有需要的朋友可以借鉴参考下,希望可以有所帮助
    2021-09-09
  • C语言小程序 数组操作示例代码

    C语言小程序 数组操作示例代码

    对数组进行操作,查找、插入、删除
    2013-07-07

最新评论