模板元编程与函数式

为什么需要模板



模板

对于string类型需要特例化
需要显式转换string,不然会把字符串常量认作const char*

默认模板参数

整数也可以作为参数,不过浮点数,指针类型,自定义类型不能声明为模板参数,不过为什么要把int类型作为模板参数呢,直接作为函数参数不行吗?因为模板里的int是编译期常量

可以有多个模板参数

参数部分特化

模板里的int和函数参数里的int有什么区别呢?

  • 根据传入的模板int参数,编译器可以做出相应的优化

  • 模板的定义和实现都必须放到头文件中?如果模板将定义与声明分离,那么链接时将会出错这里也提现了模板的惰性的特点如果一定要分离模板的声明与定义,那么需要在定义模板的文件增加所用到的模板实例化模板的惰性的证明

  • 由于模板编译的时候需要根据模板参数的变化生成不同的实例化函数,所以会使得编译变慢

编译期优化,把bool变量放到模板参数中


用C++17的if constexpr进一步保证是编译期确定的分支,也就是保证if的括号里是编译期常量

实例化模板的参数也必须得是编译器常量

可以在实例化模板的参数放入编译期常函数

模板函数打印vector还可以重载运算符实现打印

自动类型推导auto

auto的局限性

auto可以用于函数返回值,如果函数声明和实现分离了,那么就不能够在声明中使用auto
引用本质上是一个指针常量指针常量本质上是常量,也就是指针的指向不能变,int * const p //指针常量;而常量指针是指指向常量的指针,指针的指向可以变,但是只能指向常量,const int *p = &a; //常量指针

常引用就是指向常量的指针常量

懒汉单例模式是这个第一次调用函数才会初始化这个static变量

纯右值,右值类型int &&

int &&可以自动转化为int const&,但是不能够转为int &

decltype 用来返回变量的类型

decltype((a)),添加括号可以得到int&?数组取值返回的是引用是因为,比如p[0]得到的是一个左值?

万能推导(decltype(auto))?

using与typedef意思一致,但是用法更明了

decltype用于得到模板函数中的类型值

函数式编程

函数可以当作模板的参数

lambda表达式,可以作为参数

引用捕获闭包外的变量

这里传递函数的引用,由于捕获了fac 和 counter两个变量,那么传递时就是传递两个变量的指针,对于64位os,那么这个函数twice作为参数传递就是16字节

lambda表达式也可以作为返回值

这里的lambda表达式捕获一个栈中的数据,那么lambda表达式中捕获的fac的指针(引用)指向的内存就被释放了,
解决方法是用值捕获,这个时候这个函数的大小是4字节,猜测是由于值捕获把数值传递进来了

由于模板在这种情况下不能够去分离声明与定义,因为lambda表达式类型是匿名的,所以可以使用std::function

std::function开销较大,无捕获的lambda表达式可以退化为函数指针

lambda也可以模板化

使用auto表示函数模板

type traits

lmabda表达式的立即求值

lambda实现递归

tuple

CTAD(compile-time argument deduction )

C++17结构化绑定
解包为常引用
结构化绑定解包任何自定义类

std::optional

可以用*号去获取optional容器里的内容,不过它不会抛异常与检测是否为空
std::variant可以看作更加安全的union

posted @ 2022-03-22 17:50  抿了抿嘴丶  阅读(90)  评论(0)    收藏  举报