当前位置:网站首页>什么是元编程
什么是元编程
2022-08-01 13:11:00 【发如雪-ty】
元编程的英文名字是Meta Programming,也称为模板元编程,可以理解为一种编程手法,用来实现一些比较特殊的功能。元编程一般和“递归”这个词有比较密切的联系,代表着元编程这种编程手法中多数都会用到递归编程技术。
由于元编程这种手法有其特殊性,所以许多资料上会将元编程和泛型编程分开来说。其实模板编程主要应用再两个方面:1.泛型编程 2.元编程
(1)泛型编程:重点突出的是“通用”的概念,这个“泛”字就是通用的意思,程序员不需要关心具体的类型。
(2)元编程:重点突出的是一种程序设计的技巧,达到用常规的编程手段难以达到的效果。元编程可以让某些计算在编译期间完成,从而在很大程度上节约了程序运行的时间,提高程序的运行性能。
一、什么是元函数
传统的函数都是程序运行期间被调用和执行的函数,而元函数是能在编译期间被调用执行的函数(编译期间就能得到结果)。引入元函数概念的目的是支持元编程,而元函数是元编程的核心。
总结:所谓元编程,就是用元函数进行编程,甚至可以说,书写和使用这些元函数的过程本身就是在进行元编程。
c++11标准引入的constexpr关键字用于编译的时候求值,这样能够提升程序运行时的性能。
constexpr int myfun(int abc)
{
return abc*2;
}
在main函数中调用:
constexpr int var = 11*myfunc(12);
static_assert(var == 264,"sth error");
static_assert关键字是一个静态断言,是编译期间断言。如果第一个条件不满足,则提示后面的字符串。编译后没有出错。
注意:constexpr自带inline属性,这个属性是c++17标准引入的。
二、元函数分类
2.1 数值元函数
在刚才的范例,元函数myfunc()使用了constexpr关键字修饰,因为它输出的结果是一个数值,由此得名数值函数。也许有的读者可能会觉得元函数应该是个函数,其实元函数的有很多种形式,
(1)编译期间能够被调用的类模板
template<int x_v,int y_v>
struct calc
{
enum
{
addvalue = x_v + y_v,
};
};
void main()
{
const int var = calc<4, 13>::addvalue;
static_assert(var == 17, "sth error");
cout << var << endl;
system("pause");
}
结果:
随着c++语言的不断标准化,也出现了使用静态const成员变量的程序写法。所以下面的代码也是可以的:
template<int x_v,int y_v>
struct calc
{
static const int addvalue = x_v + y_v;
};
但是这样修改,可能会导致在某些情况使用了calc类模板后编译器对calc进行实例化并为addvalue分配额外的内存空间(使用enum类型的addvalue不会额外分配空间)。
再看个例子:
template<int n_v>
struct Factorial
{
enum {
value = n_v * Factorial<n_v -1>::value };
};
template<>
struct Factorial<1>
{
enum {
value = 1 };
};
void main()
{
cout << Factorial<5>::value << endl;
system("pause");
}
结果:
当n_v变为1时,编译器会实例化特化版本的Factorial,此时枚举类型的值value为1,递归结束
(2)consterpr修饰的函数
如果采用c++11的写法,那么如下:
constexpr int Factorialx(int n_v)
{
return n_v <= 1 ? 1 : (n_v * Factorialx(n_v - 1));
}
(3)constexpr修饰的变量模板
//泛化版本
template<int Arg>
constexpr int result = Arg * result<Arg - 1>;
//特化版本
template<>
constexpr int result<0> = 1;
void main()
{
cout << result<5> << endl;
system("pause");
}
2.2 类型元函数
前面介绍的都是在编译器间进行数值计算的元函数,接下来介绍编译期间类型计算的元函数。
template<typename T>
struct AddPoint
{
using type = T *;
};
void main()
{
AddPoint<const char>::type s = "I Love China!";
cout << typeid(s).name() << endl;
system("pause");
}
结果:
像AddPoint这种包含了using定义类型别名的类模板,就可以称为类型元函数,其实也就是我之前文章提到的固定萃取类模板
总结:其实在实际的编程中,元函数是一个很宽泛的概念,只要用于元编程中,在编译期间能够被调用,都可以视为元函数,不必仅限于数值元函数和类型元函数。
边栏推荐
猜你喜欢
随机推荐
LeetCode_位运算_简单_405.数字转换为十六进制数
AI目标分割能力,无需绿幕即可实现快速视频抠图
The obstacles to put Istio into production and how we solve them
windows IDEA + PHP+xdebug 断点调试
【无标题】
大中型网站列表页翻页过多怎么优化?
PIR人体感应AC系列感应器投光灯人体感应开关等应用定制方案
8. SAP ABAP OData 服务如何支持创建(Create)操作
【2022蓝帽杯】file_session && 浅入opcode
搭建LNMT架构
六石编程学:问题要面对,办法要技巧,做不好的功能要想办法
高仿项目协作工具【Worktile】,从零带你一步步实现组织架构、网盘、消息、项目、审批等功能
库函数的模拟实现(strlen)(strcpy)(strcat)(strcmp)(strstr)(memcpy)(memmove)(C语言)(VS)
PAT 1162 Postfix Expression(25)
34、树莓派进行人体姿态检测并进行语音播报
一文带你彻底厘清 Isito 中的证书工作机制
通讯录(静态版)(C语言)(VS)
MCU开发是什么?国内MCU产业现状如何
什么是一致性哈希?可以应用在哪些场景?
PAT 1163 Dijkstra Sequence(30)









