C++ template模板要点

C++模板和java泛型的区别

  1. C++的template是一个声明而不是定义,在编译期间,由编译器做检查,并由编译器在需要的场合转换成对应的C代码。
    如:你定义了一个template的函数,当你的代码里第一次调用这个函数时,编译器才会按照模板给你实际的构造出对应类型的函数出来。

  2. 而Java的泛型和C++采取的机制完全不同,它利用擦除的方式把类型参数替换为限定类型(无限定类型的替换为Object),然后再编译时插入类型安全的类型转换

  3. 优缺点

    1. 效率: C++是真实的会生成对应类型代码,这样效率就等同于自己写了重载函数了;而Java却不生成代码,只是插入类型转换,这样效率肯定没有重载函数快,如果调用次数非常多,类型转换就比较费时间了
    2. 代码量:C++会根据对应类型,生成对应代码,自然代码量会增加不少;而Java只是生成一份限定类型代码,其他的都是类型转换,代码量不会增加

C++模板使用问题

  1. 自动类型转换

    如果函数已经用了模板,编译器不再对参数进行自动类型转换

    1
    2
    3
    4
    5
    template <class T>
    swap(T& a, T& b){···};
    swap(double ,double); // success
    swap(int ,double); // error!!!
  2. 函数重载规则

    先检查有没有唯一配对的函数
    再检查有没有已经生成的模板函数
    最后找到函数模板生成模板函数

  3. 生成指定类型模板函数

    如果声明的函数参数为空,但函数内部使用了模板

    1
    2
    3
    4
    5
    template <class T>
    void function(){···}
    function<int> (); // 生成int的模板函数
    function<double> (); // 生成double的模板函数
  4. 复杂调用举例

    1. Vector< int (*) (Vector<double>&, int)>

      最外面的Vector里包含了一个函数指针,这个函数返回值为int,第一个参数是一个double类型的Vector的引用,第二个参数是int

    2. 模板包含变量

      1
      2
      template <class T, int number = 100>
      class Vector{···};

      这样的模板在调用的时候可以指定number的值:Vector<int, 1000> v1;