c++类模板
一、类模板
T可以作为标识符,typename可以用class。
#ifndef STACK1_HPP #define STACK1_HPP #include <vector> #include <stdexcept> template<typename T> class Stack { private: std::vector<T> elems; public: void push(T const &); void pop(); T top() const; bool empty() const { return elems.empty(); } }; template<typename T> void Stack<T>::push(T const& elem) { elems.push_back(elem); } template<typename T> void Stack<T>::pop() { if(elems.empty()) { throw std::out_of_range("Stack<>::pop(): empty stack"); } elems.pop_back(); } template<typename T> T Stack<T>::top() const { if(elems.empty()) { throw std::out_of_range("Stack<>::top(): empty stack"); } return elems.back(); } #endif // STACK1_HPP
测试用例:
#include <iostream> #include <string> #include <cstdlib> #include "stack1.hpp" int runTest() { try { Stack<int> intStack; Stack<std::string> stringStack; intStack.push(7); std::cout<<intStack.top()<<std::endl; stringStack.push("hello"); std::cout<<stringStack.top()<<std::endl; stringStack.pop(); stringStack.pop(); } catch(std::exception const &ex) { std::cerr<<"Exception: "<<ex.what()<<std::endl; return EXIT_FAILURE; } }
二、类模板的特例化
#ifndef STACK2_HPP #define STACK2_HPP #include <deque> #include <string> #include <stdexcept> #include "stack1.hpp" template<> class Stack<std::string> { private: std::deque<std::string> elems; public: void push(std::string const &elem); void pop(); std::string top() const; bool empty() const { return elems.empty(); } }; void Stack<std::string>::push(const std::string &elem) { elems.push_back(elem); } void Stack<std::string>::pop() { if(elems.empty()) { throw std::out_of_range("Stack<std::string>::pop(): empty stack"); } elems.pop_back(); } std::string Stack<std::string>::top() const { if(elems.empty()) { throw std::out_of_range("Stack<std::string>::top(): empty stack"); } return elems.back(); } #endif // STACK2_HPP
三、缺省模板实参
#ifndef STACK3_HPP #define STACK3_HPP #include <vector> #include <stdexcept> template <typename T, typename CONT = std::vector<T> > class Stack { private: CONT elems; public: void push(T const &elem); void pop(); T top() const; bool empty() const { return elems.empty(); } }; template <typename T, typename CONT> void Stack<T,CONT>::push(const T &elem) { elems.push_back(elem); } template <typename T, typename CONT> void Stack<T,CONT>::pop() { if(elems.empty()) { throw std::out_of_range("Stack<>::pop(): empty stack"); } elems.pop_back(); } template <typename T, typename CONT> T Stack<T,CONT>::top() const { if(elems.empty()) { throw std::out_of_range("Stack<>::top(): empty stack"); } return elems.back(); } #endif // STACK3_HPP
测试用例:
int runTest3() { try { Stack<int> intStack; Stack<double, std::deque<double> > dblStack; intStack.push(7); std::cout<<intStack.top()<<std::endl; dblStack.push(42.42); std::cout<<dblStack.top()<<std::endl; dblStack.pop(); dblStack.pop(); } catch(std::exception const &ex) { std::cerr<<"Exception: "<<ex.what()<<std::endl; return EXIT_FAILURE; } }
无欲速,无见小利。欲速,则不达;见小利,则大事不成。