1、菰灞巴静举例子除了可以申明函数模板外,也还可以声明类模板。举个例子(实现一个堆栈):template<typename T&爿讥旌护gt;class Stack {std::vector<T> v;public:Stack();Stack(const Stack<T>&); // T是同一类型的类模板才能拷贝Stack<T>& operator=(const Stack<T>&);void push(const T&);void pop();const T& top() const;bool empty() const;};template<typename T>Stack<T>::Stack(){}template<typename T>Stack<T>::Stack(const Stack<T>& rhs) : v(rhs.v){}template<typename T>Stack<T>& Stack<T>::operator=(const Stack<T>& rhs){v = rhs.v;return *this;}template<typename T>void Stack<T>::push(const T& x){v.emplace_back(x);}template<typename T>void Stack<T>::pop(){assert(!v.empty());v.pop_back();}template<typename T>const T& Stack<T>::top() const{assert(!v.empty());return v.back();}template<typename T>bool Stack<T>::empty() const{return v.empty();}

2、定义好类模板后,它的调用方法:int main(){using IntStack = Stack<int>; // typedef Stack<int> IntStackIntStack intStack; // Stack<int> intStackintStack.push(42);std::cout << intStack.top(); // 42Stack<std::string> stringStack;stringStack.push("hi");std::cout << stringStack.top(); // histringStack.pop();}

4、成员函数只有被调用到时才实例化如果类模板有static数据成员,每种实例化类型都会实例化static数据成员。static成员函数和数据成员只被同类型共享template<typename T>class A {static std::size_t n;public:static std::size_t count();};template<typename T>std::size_t A<T>::n = 0;A<std::string> a; // 实例化A<std::string>::nA<int> b, c, d; // 实例化A<int>::n,bcd共享A<int>::count()和A<int>::nstd::size_t n = A<int>::count(); // 实例化A<int>::count()n = b.count(); // 使用A<int>::count()n = A::count(); // 错误:必须指定模板参数,否则无法得知实例化版本

6、与其使用printOn函数打印元素,不如重载operator<<,然而通常operator<<会实现为非成员函数。下面在类内定义友元,它是一个普通函数template<typename T>class Stack {...void printOn(std::ostream& os) const;friend std::ostream& operator<<(std::ostream& os, const Stack<T>& stack) {stack.printOn(os);return os;}};

8、二是将友元前置声明为模板,而友元参数中包含类模板,这样就必须先前置声明类模板template<type荏鱿胫协name T> // operator<<中参数中要求Stack模板可见class Stack;template<typename T>std::ostream& operator<<(std::ostream&, const Stack<T>&);// 随后就可以将其声明为友元template<typename T>class Stack {…friend std::ostream& operator<< <T> (std::ostream&, const Stack<T>&);};// 类外定义template<typename T>std::ostream& operator<<(std::ostream& os, const Stack<T>& stack){stack.printOn(os);return os;}
