• C++模板与泛型编程


    模板是C++中泛型编程的基础,一个模板就是一个创建类或函数的蓝图。

    函数模板

    我们可以定义一个通用的函数模板(function template),而不是为每个类型都定义一个新函数。compare的模板版本如下:

    1
    2
    3
    4
    5
    6
    7
    template <typename T>
    int (const T &v1, const T &v2)
    {
    if (v1 < v2) return -1;
    if (v2 < v1) return 1;
    return 0;
    }

    模板定义以关键字template开始,后跟一个模板参数列表(template parameter list),这是一个逗号分隔的一个或多个模板参数(template parameter),用尖括号包围。
    实例化函数模板:

    1
    2
    3
    4
    5

    cout << compare(1, 0) << endl; // T为int
    // 实例化出int compare(const vector<int>&, const vector<int>&)
    vector<int> vec1{1, 2, 3}, vec2{4, 5, 6};
    cout << compare(vec1, vec2) << endl; // T为vector<int>

    类型参数前必须使用关键字classtypename

    1
    2
    3
    // 在模板参数列表中,typename和class没有什么不同
    template <typename T, class U>
    T calc(const T&, const U&);

    类模板

    类模板(class template)是用来生成类的蓝图。与函数模板的不同之处是,编译器不能为类模板推断模板参数类型,必须在模板名后面的尖括号中提供额外信息——用来替代模板参数的模板实参列表。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82

    using std::cout;
    using std::endl;
    #include <string>
    using std::string;
    #include <memory>
    大专栏  C++模板与泛型编程/>using std::shared_ptr;
    using std::make_shared;
    #include <vector>
    using std::vector;

    using std::initializer_list;
    using std::out_of_range;

    template <typename T> class Blob {
    public:
    typedef T value_type;
    typedef typename vector<T>::size_type size_type;
    Blob();
    Blob(initializer_list<T> il);
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }
    void push_back(const T &t) { data->push_back(t); }
    // 移动版本
    void push_back(T &&t) { data->push_back(move(t)); }
    void pop_back();
    T &back();
    T &operator[](size_type i);
    private:
    shared_ptr<vector<T>> data;
    void check(size_type i, const string &msg) const;
    };

    // 默认构造函数
    template <typename T>
    Blob<T>::Blob(): data(make_shared<vector<T>>()) { }

    // 构造函数
    template <typename T>
    Blob<T>::Blob(initializer_list<T> il):
    data(make_shared<vector<T>>(il)) { }

    // 检查数组是否越界
    template <typename T>
    void Blob<T>::check(size_type i, const string &msg) const
    {
    if (i >= data->size())
    throw out_of_range(msg);
    }

    // 删除最后一个元素
    template <typename T>
    void Blob<T>::pop_back()
    {
    check(0, "pop_back on empty Blob");
    data->pop_back();
    }

    // 返回最后一个元素
    template <typename T>
    T &Blob<T>::back()
    {
    check(0, "back on empty Blob");
    return data->back();
    }

    // 重载下标运算符,返回元素的引用
    template <typename T>
    T &Blob<T>::operator[](size_type i)
    {
    check(i, "subscript out of range");
    return (*data)[i];
    }

    int main()
    {
    Blob<int> squares = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    for (size_t i = 0; i != squares.size(); ++i)
    squares[i] = i * i;
    cout << squares.back() << endl;
    return 0;
    }

  • 相关阅读:
    多点触控版的驱动安装
    模板类的继承
    c++大整数运算
    RHEL6单用户模式切换
    Dlna相关开源项目收集整理
    给我的当前RHEL6新增一块硬盘!
    交叉编译libconv
    OSCam学习记录
    Android中的应用!!!!
    Elf文件格式学习笔记
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12255790.html
Copyright © 2020-2023  润新知