C++模板编程(5)---实际运用模板:显式实例化(Explicit Instantiation)

上文中的置入式模型inclusion model 保证所有用到的template都能被实例化。之所以有这层保障,是因为C++编译器会在template被使用时自动实现它。C++标准提供了另一种方式,可以手动将template实例化。这种方式称为显示实例化指令(explicit instantiation directive)。

1. 显示实例化(Explicit Instantiation)示例

可以为上文中有链接错误的工程,添加如下文件

//myfirstinst.cpp

//明确以double类型将print_typeof()实例化

template void print_typeof<double> (double const&);

这个显示实例化指令由两部分组成:

  • 关键词 template
  • 一个模板参数已被完全替换后的函数声明。

本例是对函数做显示实例化动作,也可以运用相同的手法对一个成员函数或一个static成员变数做显式实例化动作。如:

//明确以int类型对MyClass<>的构造函数进行实例化操作

template MyClass<int>::MyClass();

//明确以int类型对function template max<> 进行实例化操作

template int const& max (int const&, int const&);

也可以显式实例化一个类模板。这是一个简便做法,相当于要求编译器具体实例化该class template的所有可被实例化的成员,但不包括先前已被特化或已被实例化的成员:

//明确地以int类型对Stack<> class 进行实例化动作

template class Stack<int>:

//明确以 string类型对Stack<>的一部分成员进行实例化操作

template Stack<std::string>::Stack();

template void Stack<std::string>::push(std::string const&)

template std::string Stack<std::string>::top() const;

//不能对已被实例化的某个成员再次实例化,下面代码错误

template Stack<int> :: Stack();

明显的,程序中显式实例化语句只能出现一次,否则链接器报重复定义错误。这就要求我们必须非常仔细搞清楚该实例化哪些物体。

然而,显式实例化也有一些好处,实例化动作可以根据程序需求进行最佳调整。且避免包含巨大的头文件。另外,控制模板实例化在某个精确位置(object file)有时很有用,而自动实例化不能做到这一点。

2. 结合置入式模型(Inclusion model)和显式实例化(Explicit Instantiation)

为了进一步讨论该使用置入式模型或使用显式实例化,我们将模板的声明语句和定义语句分别置于两个不同的文件。通常会将这两个文件的扩展名看起来像头文件(可被包含)。这样,我们把先前myfirst.cpp改名为myfirstdef.hpp,并在首尾加上防止可重复包含的预处理指令。如下图

 

现在,我们

  • 想使用置入式模型,可以简单地将定义式的头文件 stackdef.hpp包含进来。

//main.cpp

 //stackdef.hpp

//stack.hpp

 

 

  • 如果想要使用显式(明确)实例化,可以将声明语句所在的头文件 stack.hpp包含进来,且提供一个.c 文件,其中有必要的实例化指定,见下图,

//新增文件stack_inst.cpp 内容如下,

说明如下:

1)添加头文件stackdef.hpp

2)  添加4个显式声明 

//main.cpp,修改如红线

其他两个文件内容不变

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值