★07.关于类模板

简述

  • 类模板:是类类型的模板,如:vector
  • 模板类:类模板的实例化,如:vector
  • 类模板的模板参数无法通过模板参数自动推断来确定,必须显式指定。

定义

类模板的定义和声明必须放在头文件中

template
class A {
public:
    A();
    void fun1();
    void fun2() {}   // 定义在模板内部
};

template
A::A() {
}

template
void A::fun1() {
}

特化

代码

template 
class A {
public:
    A() { std::cout << "A" << std::endl; }
};

template <>
class A {
public:
    A() { std::cout << "A" << std::endl; }
};

int main() {
    A a1;
    A a2;
    return system("pause");
}

输出结果

A
A

特化成员函数

template 
class A {
public:
    void fun() {
        std::cout << "A::fun()" << std::endl;
    }
};

// 只特化类模板的部分成员
template <>
void A::fun() {
    std::cout << "A::fun()" << std::endl;
}

前置声明与友元声明

// 前置声明不需要给出模板参数
template  class A1;
template  class A2;


template 
class B {
public:
    friend class A1;                      // 一对一友元关系
    friend class A2;                    // 多对某一友元关系
    template  friend class A3;     // 多对多友元关系,也有前置声明的作用
};

// 类模板的特化
template <>
class B {
public:
    friend class A2;                    // 某一对某一友元关系
    template  friend class A3;     // 某一对多友元关系,也有前置声明的作用
};

可以省略模板实参的情况

template 
class A {
public:
    // 类模板作用域内可以直接使用类模板名字而不必提供模板参数
    // 即模板作用域内直接使用类模板名A时,编译期会解读为A
    A fun1(A a) {
        A b;
        return b;
    }

    A fun2(A a);
};

// 类模板作用域外不可以直接使用类模板名A取代A
template 
A A::fun2(A a) {
    // 类模板成员函数的形参列表及其函数体属于类模板作用域内
    A b;
    return b;
}

模板类型别名

template  using name1 = pair;
template  using name2 = pair;

int main() {
    name1 t1;          // t1是一个pair
    name2 t2;          // t2是一个pair
    return system("pause");
}

使用模板参数的类型成员

class A {
public:
    typedef int value_type;
};

template 
class B {
public:
    typedef typename T::value_type type;

    typename T::value_type fun() {
        return typename T::value_type();
    }
};

默认模板实参

template 
class A {
};

int main() {
    A<> a1;                 // A
    A a2;           // A
    A a3;   // A
    return system("pause");
}

显式实例化

显式实例化类模板时会显式实例化其所有成员。

// 显式实例化的作用是避免编译器多次重复实例化啊,可以达到加快编译速度的效果
// 下述代码不能同时出现在一个文件中
template class A;                // 定义,代表在此处将类模板A实例化为A
extern template class A;         // 声明,代表承诺在别的文件中有个A实例化

你可能感兴趣的:(★07.关于类模板)