c++模板编程基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liunan199481/article/details/84952356

谈c++模板编程

  • 说模板编程,第一个想到的却是c++ STL的容器。STL的容器都是采用模板编程完成的,之所以称为容器,我想也是因为模板编程赋予了他多变的存储与处理对象的能力。
  • 就拿set来说吧
set<int> int_set;//这样这个set就是int类型的容器了
set<std::string> string_set;//这样这个set就成了string类型的容器了 
  • 这完全得益于模板编程赋予代码的灵活能力。

模板函数

  • 首先我们想一下,既然是模板,而且在编译的时候根据具体的类型再生成对应的代码;那么,我们是不是要一个占位啊,所以这个玩意出来了:
template <class T>
template <typename T>
  • 这两种形式都可以,因为我们只是想告诉编译器,我先声明一个类型T,现在这占着一个位置,等后面我用啥类型,你再生成对应的代码。所以既然T是一个类型了,那么它就可以像其它类型一样,能在一些地方使用,比如:
template <class T>
T function_name(T a, T b)
{
	return a+b;
}

在这段代码里,类型T有两种用法,也是通常的用法。
1、模板类型T作为返回值类型。
2、模板类型T作为参数类型。

模板类

  • 其实上面模板函数搞懂了,大概思想就懂了,可能有些具体的写法不太一样。比如在实现类函数的时候,写的形式有点区别。

1、首先声明一个占位的类型
2、在类函数中要使用的地方使用它
3、实现类成员函数中使用它,类名后面要加上模板类型。

  • 下面例子直接从网上copy的,不喜勿喷。
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack { 
  private: 
    vector<T> elems;     // 元素 
 
  public: 
    void push(T const&);  // 入栈
    void pop();               // 出栈
    T top() const;            // 返回栈顶元素
    bool empty() const{       // 如果为空则返回真。
        return elems.empty(); 
    } 
}; 
 
template <class T>
void Stack<T>::push (T const& elem) 
{ 
    // 追加传入元素的副本
    elems.push_back(elem);    
} 
 
template <class T>
void Stack<T>::pop () 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::pop(): empty stack"); 
    }
    // 删除最后一个元素
    elems.pop_back();         
} 
 
template <class T>
T Stack<T>::top () const 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::top(): empty stack"); 
    }
    // 返回最后一个元素的副本 
    return elems.back();      
} 
 
int main() 
{ 
    try { 
        Stack<int>         intStack;  // int 类型的栈 
        Stack<string> stringStack;    // string 类型的栈 
 
        // 操作 int 类型的栈 
        intStack.push(7); 
        cout << intStack.top() <<endl; 
 
        // 操作 string 类型的栈 
        stringStack.push("hello"); 
        cout << stringStack.top() << std::endl; 
        stringStack.pop(); 
        stringStack.pop(); 
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        return -1;
    } 
}
  • 在类的声明中和上面的模板函数差不多,主要是成员函数的实现部分。
  • 在成员函数的实现中,有2点要注意;

1、每个函数的实现前都要独立声明一下模板类型。

template <class T>

2、类的后面要加上模板类型。

T Stack<T>::top () const
  • 至于模板函数怎么用,和容器的用法一致。
  • 有啥好处呢?个人感觉代码复用真的很好用。

猜你喜欢

转载自blog.csdn.net/liunan199481/article/details/84952356