TMP(1)

简介

元编程是更高层次的抽象,对代码进行编程。把程序甚至自己作为输入数据来处理,比如py的虚拟机就是元程序,它处理py的代码把其转换成py的虚拟机指令。称py为输入语言domain language,称输出的语言字节码为host language

根据是否使用了domain-language将元编程分为2类

  • 使用domain language的meta programming,普通程序和元程序是分离的
  • 直接使用host language来实现元编程,通常通过编译机制,将元编程代码生成逻辑代码,然后和其他的逻辑代码合并在一起,看起来像“逻辑代码自己改写自己”,c++的TMP属于这种。

c++模板元编程

模板通过编译器生成其他c++代码,然后和其他的c++代码一起编译

template
struct binary {
    //static constexpr int value = binary::value << 1 | N % 10;
    enum {
        value = binary::value << 1 | N % 10,
    };
};

template<>
struct binary<0> {
    enum {
        value = 0,
    };
};

//证明编译期代码1
static char array[binary<101>::value];
//证明编译期代码2
template
struct A{};
A::value> a;

小技巧c++中 如果包含static关键字的东西,大概率是编译期确定的,反正dynamic关键字通常是运行时确定的,比如dynamic_cast,dynamic

c++模板已经被证明是图灵完备的了,意味着通过计算机表达的任何计算都可以用tmp来实现

学习tmp的原因

  1. 可以编译期计算,提升运行时效率,通常会导致编译期时间变长,以及编译出的文件大小变大

  2. 可以针对类型做计算,由于c++缺少自省机制

    if(typeof(var) == int){}else{} //psedo code
    
    
  3. tmp可以让代码变得简单优美

    py::class_("m","Student")
     .def (py:init())
     .def ("set_name",&Student::set_name)
    
  4. tmp应用比较广泛且是未来趋势,比如asio,比如boost

模板基本概念

可以声明5中不同的模板

  • template struct class_tmpl;
  • template void func_tmpl(T );
  • template var_tmpl;//变量模板 c++ 14
  • template using alias_tmpl = T; //别名模板 c++11
  • template concept no_constrant = true; //c++ 20

前3个模板都可以用于定义,后两个不需要定义,不产生运行时的实体

  • template struct class_tmpl{}
  • template void func_tmpl(T arg){}
  • template var_tmpl = T(3.14);

c++14中有范型lambda,但是不是模板,是普通的lambda,但是它的operator()函数是个模板

auto glambda = [](T a,auto && b){return a

模板形参和实参

template struct NoneTypeTemplateParameter {};                //非类型形参
template struct TypeTemplateParameter {};               //类型模板形参
template typename tmpl> struct TemplateTemplateParameter {};   //模板模板形参

//应用
NoneTypeTemplateParameter<1>();
TypeTemplateParameter();
TemplateTemplateParameter();

非类型模板形参只接受“结构化类型常量”

  • 整形 int char,long等
  • enum类型
  • 指针和左值引用
  • 浮点类型 以及 字面常量 literal class type (c++ 20 后才支持)
template void foo() {std::cout<(); // 0.1f
foo(); // error 模板实参需要编译期可以推导

模板模板形参 只接受 类模板 或者类的别名模板作为实参,不接受函数模板,且形参和实参的模板参数匹配

template