【C++模板编程】

title: 8.6.11&12 模板编程 tags: notebook: 8.0 工作准备

一、 模板概念

C++ 的抽象机制

  • 面向对象:要了解编译知识
  • 泛型编程:设计通用的类型或算法
  • 元编程:使用模板进行选择和迭代,通过模板设计程序

模板多态

  • 静态

二、泛型编程

函数模板

匹配优先级:先匹配普通函数,再匹配特化模板函数,最后是通用模板函数。

模板函数

  • 由代码决定生成多少个模板函数,导致程序变大
template<typename T>
void add(T a, T b) {
    ...
}

特化模板

  • 一定要写到通用模板后面
template<typename T>
void add(T a, T b) {
    ...
}
template<>
void add(int a, int b) {
    ...
}

返回值类型

  • C++14可以用auto进行返回值推导
  • C++11 可以用decltype( )进行类型推导,返回是类型
    • 返回值后置
template<typename T, typename U>
auto add(T a, T b)->decltype(a + b) {
    return a + b;
}

T&&

  • 在模板编程中表示既匹配左值,又匹配右值

万能的引用传递

  • 在模板函数中,类型为左值引用
  • 配合std::forward<T>( )使用,可以转换为传进来的类型
  • 如何把模板的左值引用改为普通左值类型
typename std::remove_reference<T>::type c = a;

模板类

模板类

template<typename U>
class Print
{

}
  • 模板类也可以指定类型,然后特化指定数值

模板类的特化

template<>
class Print<int>

  • 对指定类型的模板进行特化,特化传入的为数值

变参模板

定义方式

template<class T, class ...ARGS>
void print(T& t, ARGS ...args) {


}

三、元编程

图灵完备性

  1. 要有基本的数据类型
  2. 需要某种方法,将基础的类型组合起来
  3. 需要流程控制。例如顺序、分支、循环
  4. 需要输入、输出。

编译时处理的变量

  • using
  • #define
  • constexpr

练习1

  • 实现sum函数
#include <iostream>

using namespace std;

template<int N>
struct mySum {
    static constexpr int value = \
        mySum<N - 1>::value + N;
};

template<>
struct mySum<0> {
    static constexpr int value = 0;
};

int main(int argc, char const *argv[]) {
    cout << mySum<100>::value << endl;
    return 0;
}

四、类型萃取

#include <iostream>
#include <vector>

using namespace std;


// 不使用类型萃取,无法计算int[] 的sum值
// 原因:传入的指针没有value_type
template<class iter>
typename iter::value_type MySum(iter b, iter e) {
    typename iter::value_type res{0};
    for (iter i = b; i != e; i++) {
        res += *i;
    }
    return res;
}

//类型萃取:特化没有value_type的指针类型
template<typename iter>
struct transType {
    // 注意:这里要加typename
    using value_type = typename iter::value_type;
};
template<typename iter>
struct transType<iter*> {
    using value_type = iter;
};

template<class iter>
typename transType<iter>::value_type MySum2(iter b, iter e) {
    typename transType<iter>::value_type res{0};
    for (iter i = b; i != e; i++) {
        res += *i;
    }
    return res;
}



int main(int argc, char const *argv[])
{
    vector<int> arr{1, 2, 3, 54, 7};
    
    cout << MySum(arr.begin(), arr.end()) << endl;

    int arr2[] = {1,2,4,5,4124};
    cout << MySum2(arr2, arr2 + 5) << endl;


    return 0;
}

其他

  • 模板不能写在cpp中
  • 模板类成员方法不能用虚函数
    • 虚函数表是在编译中生成
    • 如果使用模板,则.h文件会遍历所有cpp文件,做不到
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值