[C++] 模板

定义模板时, 使用关键字typename还是class没有区别,两个都可以用。

1 函数模板

下例是函数模板的定义及使用,可以看出,函数模板的调用方式同一般函数:

// returns 0 if the values are equal, 1 if v1 is larger, -1 if v1 is smaller
template <typename T> // 模板参数列表, 由逗号分隔,一个或多个,不能为空
   int compare(const T &v1, const T &v2)
   {
      if (v1 > v2) return 1;
      if (v1 < v2) return -1;
      return 0;
   }
int main ()  {
   // 编译器实例化为int compare(const int&, const int&)
   cout << compare(1, 0) << endl;
   // 编译器实例化为int compare(const string&, const string&)
   string s1 = "hi", s2 = "world";
   cout << compare(s1, s2) << endl;
   return 0; 
}

对于内联函数模板,inline关键字必须位于模板参数列表和函数返回类型的中间

    // OK: inline specifier follows template parameter list
     template <typename T> inline T min(const T&, const T&);

     // !!! ERROR: inline 不能放在template关键字之前
     inline template <typename T> T min(const T&, const T&);

2 类模板

类模板的定义形式及使用如下所示:

template <class Type> class Queue {
    public:
        Queue ();                  // default constructor
        Type &front ();            // return element from head of Queue
        const Type &front () const;
        void push (const Type &);  // add element to back of Queue
        void pop();                // remove element from head of Queue
        bool empty() const;        // true if no elements in the Queue
    private:
        // ...
};
int main() {
    Queue<int> qi;                 // Queue that holds ints
    Queue< vector<double> > qc;    // Queue that holds vectors of doubles
    Queue<string> qs;              // Queue that holds strings
    return 0;
}

3 模板编译模型

不同于一般函数和类定义,对于模板,编译器要求看到调用模板函数或模板类的成员函数时,也要求能看到定义。C++定义了两种编译模板代码的模型:包含编译模型(Inclusion Compilation Model) 和单独编译模型(Separate Compilation Model), 以支持声明和实现,或定义和实现分别放在头文件和源文件中的项目组织形式。

否则,要通过编译,模板的实现必须放在头文件中。

3.1 包含编译模型 (Inclusion Compilation Model)

这种编译模型,所有的编译器都支持。

// 头文件 utlities.h
#ifndef UTLITIES_H // header gaurd (Section 2.9.2, p. 69)
#define UTLITIES_H
template <class T> int compare(const T&, const T&);
// other declarations

#include "utilities.cc" // get the definitions for compare etc.
#endif
----------------------------------------------------------------
// 源文件 utlities.cc
template <class T> int compare(const T &v1, const T &v2)
{
      if (v1 > v2) return 1;
      if (v1 < v2) return -1;
      return 0;
}
// other definitions

用VS2010测试:

//file: my_template.h
#ifndef MY_TEMPLATE_H
#define MY_TEMPLATE_H
template<typename T> int compare(const T&, const T&);
#include "my_template.cpp" # Most import line for build
#endif
-----------------------------------------------------
//file: my_template.cpp
#include "stdafx.h"
// 注意,这里不能加 #include "my_template.h", 加了就无法编译通过。
template<typename T> int compare(const T& v1, const T& v2) {
    if (v1 > v2) return 1;
    if (v1 < v2) return -1;
    return 0;
}
-----------------------------------------------------
// file with main:
#include "stdafx.h"
#include "my_template.h"
#include <iostream>
using std::cout;
using std::endl;
int _tmain(int argc, _TCHAR* argv[])
{
    cout << compare(3, 1) << endl;
    system("pause");
    return 0;
}
// 可以成功执行,输出 1.

对于函数模板,这种方法ok。

但是测试中发现,对于模板类,如果加了类似 include “source.cpp” 的指令,会出现“函数模板已经定义”的错误,所以,把模板类的实现也放在头文件中,将是省时省力的做法。

3.2 单独编译模型 (Separate Compilation Model)

这种编译模型使用了关键字export

对于函数,只需在源文件中的函数定义前加export关键字。

// the template definition goes in a separately-compiled source file
export template <typename Type> Type sum(Type t1, Type t2) /* ...*/

对于类,略有不同:

// 头文件
template <class Type> class Queue { ... };
-------------------------------------------------------------
// 源文件
export template <class Type> class Queue;
#include "Queue.h"
// Queue member definitions

由于VS2010 说它不支持export关键字,这种编译模型没测试过。


[1] C++ Primer Chapter 16 Templates and Generic Programming

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值