C++模板与泛型编程
模板是C++中泛型编程的基础,一个模板就是一个创建类或函数的蓝图。
函数模板
我们可以定义一个通用的函数模板(function template)
,而不是为每个类型都定义一个新函数。compare的模板版本如下:
1234567 | 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)
,用尖括号包围。
实例化函数模板:
12345 | 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> |
类型参数前必须使用关键字class
或typename
:
123 | // 在模板参数列表中,typename和class没有什么不同template <typename T, class U>T calc(const T&, const U&); |
类模板
类模板(class template)
是用来生成类的蓝图。与函数模板的不同之处是,编译器不能为类模板推断模板参数类型,必须在模板名后面的尖括号中提供额外信息——用来替代模板参数的模板实参列表。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 | 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;} |
相关推荐
Joymine 2019-10-26
C++ 中有几种交换变量的方法?cout << "b = " << b << endl;}Swap 泛型编程中的 T 不是一个具体的数据类型,而是泛指任意的数据类型。一种特殊的函数可用不同类型进行调用
小南地带 2019-06-30
lynjay 2019-06-27
独孤依人 2019-06-27
jeonkc 2018-09-03
electricperi 2014-04-28
我叫河蟹 2012-06-27
你好C 2018-01-25