在之前的类模板中,只在类声明时用了 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}
以上类和之前定义的 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}
同样的,类模板的成员模板也只有在调用时才会实例化,否则不会。
成员模板既可以在类模板中,也可以在普通类中。
1class MyClass2{
2public:
3 template<typename T>
4 void func(T t);
5};
6
7template<typename T>
8void MyClass2::func(T t) {
9
10}
原创文章,转载请注明来源: C++ 模板系列小结04-类模板中的成员模板
相关文章
留言