注意,template template parameter 是极晚近才加入的C++ 特性,因此上面这个程序可作为一个极佳工具,用来评估你的编译器对 template 特性的支持程度。
下面的代码在vs2008通过, codeblocks 通过, vs2003不通过
- // stack8.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <deque>
- #include <vector>
- #include <iostream>
- #include <memory>
- #include <string>
- #include <exception>
- using namespace std;
- template <typename T,
- template <typename ELEM, typename = allocator<ELEM> >
- class CONT = deque >
- class CStack
- {
- public:
- void push(T const&);
- void pop();
- T top() const;
- bool empty() const;
- // 赋予一个「元素类型为 T2」的 stack
- template <class T2,
- template <class ELEM2, class = allocator<ELEM2> >
- class CONT2>
- CStack<T, CONT>& operator = (CStack<T2, CONT2> const&);
- private:
- CONT<T> m_dqElems;
- };
- template <class T, template<class, class> class CONT>
- bool CStack<T, CONT>::empty() const
- {
- return m_dqElems.empty();
- }
- template <class T, template <class, class> class CONT>
- void CStack<T, CONT>::push(T const& elem)
- {
- m_dqElems.push_back(elem);
- }
- template <class T, template<class, class> class CONT>
- void CStack<T, CONT>::pop()
- {
- if (m_dqElems.empty())
- {
- throw out_of_range("stack empty!");
- }
- m_dqElems.pop_back();
- }
- template <class T, template<class, class> class CONT>
- T CStack<T, CONT>::top() const
- {
- if (m_dqElems.empty())
- {
- throw out_of_range("stack empty!");
- }
- return m_dqElems.back(); //传回最后一个元素的拷贝
- }
- template <class T, template<class, class> class CONT>
- template <class T2, template<class, class> class CONT2>
- CStack<T, CONT>& CStack<T, CONT>::operator = (CStack<T2, CONT2> const& op2)
- {
- if ((void*)this == (void*)&op2)// 是否赋值给自己
- {
- return *this;
- }
- CStack<T2, CONT2> tmpOp2(op2);
- m_dqElems.clear();
- while (!tmpOp2.empty())
- {
- m_dqElems.push_front(tmpOp2.top());
- tmpOp2.pop();
- }
- return *this;
- }
- template <class T, template<class, class> class CONT>
- void PrintStack(CStack<T, CONT> const& objStack)
- {
- //做一个copy打印
- CStack<T, CONT> tmpStack(objStack);
- while (!tmpStack.empty())
- {
- cout << tmpStack.top() << "/t";
- tmpStack.pop();
- }
- cout << endl;
- }
- int main()
- {
- int i = 0;
- try
- {
- CStack<int> intStack;
- CStack<float> floatStack;
- for (i = 0; i < 10; i++)
- {
- intStack.push(11 * i);
- }
- cout << "intStack contents: " << endl;
- PrintStack<int>(intStack);
- floatStack = intStack;
- cout << "floatStack contents: " << endl;
- PrintStack<float>(floatStack);
- }
- catch (exception const& exp)
- {
- cerr << "Exception: " << exp.what() << endl;
- }
- CStack<int, vector> vtStack;
- for (i = 0; i < 10; i++)
- {
- vtStack.push(2 * i);
- }
- PrintStack<int, vector>(vtStack);
- return 0;
- }