模版元编程、自动类型推导 与 函数式编程

关于模版元编程和函数式编程,涉及到的是C++的5种编程范式,i.e.

  1. 面向过程
  2. 面向对象
  3. 函数式
  4. 范型
  5. 模版元编程

模版元编程

元编程(metaprogramming)是指编写能够生成或操作其他程序的程序。

  1. 写在尖括号内的包含两种内容:模版类型参数和非模版类型参数
  2. 可以为模版类型参数指定默认值
  3. 非模版类型参数同普通函数相比,前者是编译时常量,后者是运行时常量,编译器可以对前者在编译时进行优化(可通过constexpr指定某一变量是编译时常量)
  4. 可定义多个模版参数
  5. 除非使用特殊手段,否则应将模版的声明和定义放置在一起,无法使用头文件函数声明和cpp文件函数定义分离的方式,问题在于会使二进制文件大小过大

调用函数模版,编译器推断模版参数类型的过程称为模版实例化,编译器在面对函数模版的定义时,是不生成代码的,只有当模版实例化时,才会真正生成代码,此性质称为延迟编译(不过在mac上的实际表现并非如此,可能和mac的编译器有关)
函数模版的原理是在编译时生成多份函数,编译器根据实例化代码生成对应类型的函数

模版的困难点在于编译期常量的限制,即所有涉及到模版参数的参数都必须是编译期常量,可通过constexpr关键字显示指定使得某些运行时常量变为编译时常量。

需要注意模版参数使用classtypename的区别


自动类型推导auto
使用要求:

  • 声明变量的同时必须进行赋值,否则类型无法推导
  • 类成员变量不允许声明为auto
    万能推导 decltype(auto)

函数式编程

注意和函数指针进行区分,函数指针示例如下

#include <iostream>

void func() {
	std::cout << "call func()" << std::endl;
}

int main() {
	void (*p)() = func;

	p(); // output: call func()

	return 0;
}
  1. 函数作为函数参数,作为返回值(如果为了声明和定义分离提高编译速度而不能使用auto,可以采用std::function)
  2. lambda表达式
  • 变量捕获:如果不进行变量捕获,则使用[],那么lambda函数体内是无法使用处于lambda参数列表之外且定义于lambda位置的其他变量。使用[&]实现lambda捕获定义它的位置中的变量,同时这一特性称为闭包(closure)。变量捕获需要保证lambda的生命周期要不超过引用变量的生命周期,即lambda存在时引用必须存在。为了解决这一问题,可以采用[=],即不采用引用,而是直接将数据进行拷贝

Reference

posted @ 2023-09-03 12:42  0x7F  阅读(6)  评论(0编辑  收藏  举报