★07.关于类模板

2017-06-30  本文已影响0人  iDragonfly

简述

定义

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

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

template<typename T>
A<T>::A() {
}

template<typename T>
void A<T>::fun1() {
}

特化

代码

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

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

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

输出结果

A<T>
A<double>

特化成员函数

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

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

前置声明与友元声明

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


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

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

可以省略模板实参的情况

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

    A fun2(A a);
};

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

模板类型别名

template <typename T> using name1 = pair<T, T>;
template <typename T> using name2 = pair<T, char>;

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

使用模板参数的类型成员

class A {
public:
    typedef int value_type;
};

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

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

默认模板实参

template <typename T = int, typename F = double>
class A {
};

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

显式实例化

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

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

猜你喜欢

热点阅读