C++ template Day Day Up 第一天 模板编译模式

来源:互联网 发布:关于80后的网络段子 编辑:程序博客网 时间:2024/05/21 10:52
痴迷于OO设计,在C++的应用中运用模式或者设计的时候却总是畏首畏脚的,怕没有回收内存,怕产生临时变量,怀念java和C#带给我们的方便,C++真的不行么?Linus那臭小子真的言中了?我不信,他的言论只是利用他的技术权威在进行的商业行为。
那么C++程序到底应该怎么设计和编码才是优雅的、方便的呢? 无意间看了 Modern C++ design, 才明白原来template + OO 才是真正的Cpp-Style design,之后放下手中的其它技术,潜心研究template,希望也能轻松驾驭template于项目之中,作出更优秀的设计。
Cpper手中两把最锋利的武器是OO和template。 OO我们已经很熟悉了,而template的高级应用对于大多数C++程序员(至少我了解到的是)来讲还是挺遥远的,用且用得少(像boost,loki, STL也只用了一小部分),更何况作出漂亮的设计呢。
So,准备写一篇长篇科普blog,与Cpper共同进步。能力有限,水平有限,谅解 my mistakes。
 
Action!
Today's attention!
编译最简单的模板函数 Max
写一个比较int类型的Max
int Max(int l, int r)
{
    return l > r? l : r;
}
像很多书中介绍的一样,有了template我们可以写出这样的程序:
template <typename T>
T Max(T a, T b)
{
    return a > b ? a : b;
}
很好~ 这段程序不准备介绍,本篇的重点是如何编译template程序。
直接编译不就得了? 实际上这里面是有学问的。
下面将介绍编译C++ template的两种模式
无论函数或者类,传统C++是分为头文件(h, hpp…)和定义文件(cpp…)来定义一个函数。
在头文件中写上声明,在实现文件中写明定义。类似如下形式:
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
//Max.cpp
 
#include “Max.h”
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
//
Max(1, 2);
编译上面的程序的时候compile会通过,link会失败。这说明编译器不能像对待普通函数或者类一样对待template。
Template 编译模式一:
Inclusion Model
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
或者
//Max.cpp
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
///////////////////////////////
// Max.h
template <typename Type>
Type Max(Type a, Type b);
#include “Max.cpp”
////
当然你也可以直接写出函数定义。
// Max.h
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
实际上Inclusion Model就是将定义和实现全都放到头文件中,这对于template class的定义也是一样的,让我们前瞻一下template class
 
template <typename T>
class TryDef
{
public:
     T getDefaultObject();
};
 
template<typename T>
T TryDef<T>::getDefaultObject()
{
     return T();
}
 
恩~ 这个就是Inclusion Model,大多数情况我们就用这种模式。
 
Template 编译模式二:
Explicit Instantiation
 
这种模式隐含着C++一个语法。
 
template int Max(int a, int b);
看上面这行语句,这是定义了一个模版的实例,编译期间会根据这条语句直接生成一个int的Max函数,而不是通过使用者调用int版的Max函数在生成实例。
 
假如我们想要完成这样一个需求: 对于一个模版函数或类,我们只想生成我们指定的类型的版本,对于其他类型的版本一概不给出实现,如果用户调用就会出现连接错误。
 
这时候Explicit Instantiation 模式就派上用场了,我们这样组织源程序:
// Max.h
template <typename Type>
Type Max(Type a, Type b);
 
//Max.cpp
 
#include “Max.h”
template <typename Type>
Type Max(Type a, Type b)
{
       return a > b ? a : b;
}
 
//MaxInst.cpp
 
#include “Max.cpp”
 
template float Max(float, float);
 
假如我们这样调用函数,
#include “Max.h”
Max(1, 2);
编译器会给出连接错误。
想让它编译通过的话需要加上int版本的Max函数,在MaxInst.cpp中加入:
template int Max(int,int);
 
还有一种编译模式常用的编译器都没有实现,叫做Separation Model,它利用export关键字,没法尝试所以偶就保持沉默了。
 
 
Summary
 
以上示例程序在Visual Studio 2005 g++ 3.4.2下通过验证。
 
原创粉丝点击