原创 【博客大赛】《C++ Primer》学习笔记(34/END)Templates and Generic Programming

2016-5-16 21:26 1270 20 21 分类: MCU/ 嵌入式 文集: Qt和Cpp

Object-oriented programming和generic programming处理的是类似的问题,
那就是——未知的数据类型。
前者处理的是运行时的未知,后者处理的是编译时的未知。

vector、迭代器、算法等,都属于generic program,而templates是generic编程的基础。
如果我们想设计一个generic类型,比如vector,或者编写一个generic函数,比如find,
此时templates就是我们的blueprint。

16.1 Defining a Template
----------------------------------------------------------------
函数模板是一个公式,我们可以使用它产生特定类型的函数版本,
比如:
template <typename T>
int compare(const T &v1, const T &v2)
{
    if (v1 < v2)
        return -1;
    if (v1 > v2)
        return 1;
    return 0;
}

而它们在运行的时候所产生的version,被称为模板的实例化(instantiation)。

下面的表达式不合法:
template <typename W, U> W calc(const W &t1, const U &u1);
需要修改为:
template <typename W, class U> W calc(const W &t1, const U &u1);

另外,template还可以用来表示某一类型的value值:
template <unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
    return strcmp(p1, p2);
}

这样的template参数,我们称之为nontype,它可以是int、指针、lvalue的引用、函数类型,
但是它必须是一个constant表达式,必须具备static lifetime。
因为template的类型必须要在编译时被确定,而不是运行时。

 * 函数参数in the template,必须是references to const。
 * 函数体内的test,仅仅使用了“<”。

使用references to const,我们就可以保证函数可以运行在不能被copy的对象上,
虽然到目前为止,除了unique_ptr和IO类型外,大部分数据类型都可以被copy。
另外,运用在大对象时,它能跑得快点。

除了函数模板,还有类模板。
某些时候,typename和class在模板里面的含义是一样的,但是为了方便起见,统一使用前者吧!

如果类模板的构造函数里面,有模板变量,那么我们必须使用尖括号来指定类型:
template <typename T = int> class Numbers {
public:
    Numbers(T v = 0): val(v) {}
private:
    T val;
};

int main(int argc, char *argv[])
{
    Numbers<long double> lots;
    Numbers<> aver;
}

(a) template <typename T, U, typename V> void f1(T, U, V);
    错误,模板的参数列表必须每个单独有typename。
(b) template <typename T> T f2(int &T);
    错误,T不可复用为变量名。
(c) inline template <typename T> T foo(T, unsigned int*);
    错误,inline关键字必须在template之后。
(d) template <typename T> f4(T, T);
    错误,缺少返回值。
(e) typedef char Ctype;
    template <typename Ctype> Ctype f5(Ctype a);
    正确,模板参数会覆盖外面的其他name。

由于模板在使用时会被实例化,因此两个单独的源文件使用相同参数的相同模板时,它们会被分别实例化。
当项目非常大时,实例化的资源就很多了,为了避免这个问题,我们可以使用explicit instantiation:
extern template declaration;
template declaration;

16.2 Template Argument Deduction
----------------------------------------------------------------
模板函数一般不做类型转换,而是直接产生另外一个实例。
除了以下两种情况:
 * const conversions.
 * Array- or function-to-pointer conversions.

因为自动类型转换的情况非常少,因此我们尽量不要让编译器产生困惑。

16.3 Overloading and Templates
----------------------------------------------------------------
16.4 Variadic Templates
----------------------------------------------------------------
模板有可变参数,函数也有。

16.5 Templates Specializations
----------------------------------------------------------------

其实从前一小节开始,阅读已经有些困难了!
高阶内容留到对C++有足够经验的时候再学习。本学习笔记结束,算是C++正式入门啦~
今后开始了解OpenCV,Good Luck!

 

文章评论1条评论)

登录后参与讨论

用户593939 2016-5-17 22:29

写的好,参考和学习
相关推荐阅读
DiracFatCat 2018-09-05 12:14
【博客大赛】卡尔曼滤波学习笔记(11)从位置估计速度
卡尔曼滤波器,不仅仅是一个低通滤波器,否则也不会持续发展50年。 示例:桑先生需要测试高速列车的性能。测试的目的是判断列车在直线上能否保持80m/s的速度。速度和位置每0.1秒测量一次,但是由于...
DiracFatCat 2018-08-31 19:32
【博客大赛】卡尔曼滤波学习笔记(10)一个简单的示例
《Kalman Filtering: Theory and Practice Using MATLAB》第三章,看不懂,暂时略过。《Kalman Filtering: Theory and Pract...
DiracFatCat 2018-07-19 15:09
对sed命令的练习
sed是流编辑器。它每次处理一个输入,因此很有效率。官方手册:https://www.gnu.org/software/sed/manual/sed.html学习Linux命令,当然要阅读官方手册,所...
DiracFatCat 2018-06-19 15:10
【博客大赛】卡尔曼滤波学习笔记(八)可观测性和可控制性 ...
可观测性是指,在给定模型的情况下,动力学系统的状态是否由它的输入输出唯一确定。可观测性是系统模型的特征。如果传感器矩阵H是可逆的,则本系统可观测,因为有:如果传感器矩阵H某些时候是不可逆的,则本系统仍...
DiracFatCat 2018-06-19 10:56
【博客大赛】卡尔曼滤波学习笔记(七)Z变换
如果我们仅仅对离散线性系统感兴趣,那么就使用下面这个表达式:如果u是常量,那么可以写成:为了简化表达式,我们可以将上面写成:离散线性时不变系统的Φ求解,可以使用Z变换。(* 由于本人已经忘记了Z变换的...
DiracFatCat 2018-06-19 10:54
【博客大赛】卡尔曼滤波学习笔记(六)拉普拉斯变换
对于线性时变/时不变系统,求解Φ(t)有多种方式,拉普拉斯变换是其中一种。(* 由于本人已经忘记了拉普拉斯变换的内容,因此本节待续。)...
我要评论
1
20
关闭 站长推荐上一条 /2 下一条