C++ 模板系列小结04-类模板中的成员模板

技术答疑,成长进阶,可以加入我的知识星球:音视频领域专业问答的小圈子

在之前的类模板中,只在类声明时用了 typename 指定模板参数类型,之后的成员函数复用模板参数类型。

但实际上,类成员也可以是模板,嵌套类和成员函数都可以作为模板。

如下代码所示:

 1template<typename T>
 2class Stack {
 3private:
 4    std::deque<T> elems;
 5
 6public:
 7    void push(T const &elem);
 8
 9    void pop();
10
11    T top() const;
12
13    bool empty() const {
14        return elems.empty();
15    }
16
17    template<typename T2>
18    Stack<T> &operator=(Stack<T2> const &);
19};
20
21template<typename T>
22void Stack<T>::push(const T &elem) {
23    elems.push_back(elem);
24}
25
26template<typename T>
27void Stack<T>::pop() {
28    if (!elems.empty()) {
29        elems.pop_back();
30    }
31}
32
33template<typename T>
34T Stack<T>::top() const {
35    if (!elems.empty()) {
36        return elems.back();
37    }
38    throw std::out_of_range("Stack::top(); empty Stack");
39}
40
41template<typename T>
42template<typename T2>
43Stack<T> &Stack<T>::operator=(const Stack<T2> &op2) {
44    if ((void *) this == (void *) &op2) {
45        return *this;
46    }
47
48    Stack<T2> tmp(op2);
49    elems.clear();
50    while (!tmp.empty()) {
51        elems.push_front(tmp.top());
52        tmp.pop();
53    }
54    return *this;
55}
CPP

以上类和之前定义的 Stack 类略有差别,主要是自定义了赋值运算符,可以将两个不同类型的 Stack 容器内容进行转换。

在自定义的赋值运算符中,除了类模板声明的类型参数 T 之外,还多了一个 T2 的类型参数,此时的成员函数也成了一个模板函数。

在类模板中,成员函数的模板参数可以和类的模板参数不同,但在定义中必须添加两个模板参数列表。

其中,第一个为类的模板参数,第二个为成员函数的。

 1template<typename T>
 2class MyClass {
 3public:
 4    template<typename T2> 
 5    void func(T2 t2);
 6};
 7
 8template<typename T>
 9template<typename T2>
10void MyClass<T>::func(T2 t2) {
11
12}
CPP

同样的,类模板的成员模板也只有在调用时才会实例化,否则不会。

成员模板既可以在类模板中,也可以在普通类中。

 1class MyClass2{
 2public:
 3    template<typename T>
 4    void func(T t);
 5};
 6
 7template<typename T>
 8void MyClass2::func(T t) {
 9
10}
CPP

欢迎关注微信公众号:音视频开发进阶

Licensed under CC BY-NC-SA 4.0
粤ICP备20067247号
使用 Hugo 构建    主题 StackedJimmy 设计,Jacob 修改