首页 > 代码库 > c++--模板与泛型编程

c++--模板与泛型编程

 

一、定义模板

1.1 函数模板

1. 适用情况:如果两个函数几乎是相同的,唯一的差异是参数的类型,函数体则完全一样。

2. 定义

template <模板参数列表(以逗号分隔)>

1 template <typename T>
2 int compare(const T&v1,const T&v2)
3 {
4     if (v1<v2) return -1;
5     if (v2<v1) return 1;
6 }

3. 实例化函数模板
  当调用一个函数模板时,编译器用函数实参推断实参。

4. 模板参数类型

  类型参数T的用途:指定返回类型,指定函数参数类型,在函数体内用于变量声明,变量类型转换

5. 非类型模板参数

  一个非类型参数表示一个值而非一个类型。当一个模板被实例化时,非类型参数被一个用户提供的或编译器推断出的值所代替,这些值必须是常量表达式。

  用途:在模板定义内,模板非类型参数是一个常量值。在需要常量表达式的地方,可以使用非类型参数,例如,指定数组大小。

//编写一个conpare版本处理字符串字面常量。
//由于不能拷贝一个数组,所以我们将参数定义为数组的引用
template <unsigned N,unsigned M>
int compare(const char (&p1)[N],const char (&p2)[M])
{
    return strcmp(p1,p2);
}

//调用compare
compare("hi","mom");
//编译器在字符串字面常量末尾插入一个空字符作为终结符,因此编译器实例化出如下版本
int compare(const char (&p1)[3],const char (&p2)[4])

6. inline和constexpr的函数模板
template <typename T> inline T min(const T&,const T&)    //注意inline位置

7. 编码原则

  compare函数编写泛型代码的原则:模板中的参数是const 的引用;函数体中的条件判断仅使用<比较运算;

  一个原则:模板程序应该尽量减少对实参类型的要求。

8. 模板编译

注意:

  1)只有当我们实例化出模板的一个特定版本时,编译器才会生成代码。

  2)函数模板和类模板成员函数的定义通常放在头文件中。

  3)大多数编译错误发生在实例化期间报告。保证传递给模板的实参支持模板所要求的的操作,以及这些操作能正确工作,是调用者的责任。

二、类模板

  与函数模板不同之处是,编译器不能为类模板推断参数类型。为了使用类模板,必须在模板名后的< >中提供额外信息。

1. 用途:与类不同,模板可以用于更多类型的元素。

2. 定义

 

template <typename T>
class Blob
{
public:
    typedef T value_type;
    typedef typename std::vector<T>::size_type size_type;
    Blob();
    T& back();
    T& operator[](size_type i);
private:
    std::shared_ptr<std::vector<T>> data;
    void check(size_type i,const std::string &msg) const;

 

  

  

c++--模板与泛型编程