#include <iostream>
#include <vector>
#include <string>
#include <typeinfo>
#include "Stack.h"
using namespace std;
template<typename T>
T const & max(T const & a, T const & b)
{//這是個有隱患的函數模板
return a > b ? a : b;
}
template <typename T>
void ref(T const & x)
{
cout << "x in ref(T const &): " << typeid(x).name() << endl;
}
template <typename T>
void nonref(T x)
{
cout << "x in nonref(T): " << typeid(x).name() << endl;
}
int main()
{
Stack<int> intStack;
intStack.push(42);
intStack.push(7);
cout << intStack.top() << endl;
Stack<double> doubleStack;
doubleStack.push(3.5);
doubleStack.push(4.5);
cout << doubleStack.top() << endl;
//intStack = doubleStack;
//cout << intStack.top() << endl;
doubleStack = intStack;
cout << doubleStack.top() << endl;
Stack<int, vector> vStack;
vStack.push(43);
vStack.push(45);
cout << vStack.top() << endl;
string s;
cout << ::max("peach", "apple") << endl;
/*
輸出結果爲 peach
這裏的結果按道理應該是apple纔對,但爲什麼會是peach ?
這裏其實比較的是兩個字符的地址,並不是內容
*/
::max("apple", "tomato");
/*
error: no matching function for call to 'max(const char [6], const char [7])
這裏提示錯誤,指出兩個類似並不相同
*/
::max("apple", s);
/*
error: no matching function for call to 'max(const char [6], std::string&)
這裏提示錯誤,指出兩個類似並不相同
*/
ref("hello");
//x in ref(T const &): char[6]
nonref("hello");
//x in nonref(T): const char *
/*
解決方法:
1 使用非引用參數,取代引用參數
2 進行重載(但可能是產生二義性)
3 對具體類型進行重載
4 重載數組類型
5 強制要求使用者使用顯示類型裝換
*/
return 0;
}
Stack.h
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#include <queue>
template <typename T,
template<typename ELEM, typename = std::allocator<ELEM> > class CONT = std::deque>
class Stack
{
private:
CONT<T> elems;
public:
Stack():elems() {}
void push(T const &);
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}
template<typename T2,
template<typename ELEM2, typename = std::allocator<ELEM2> >class CONT2>
Stack<T, CONT>& operator = (Stack<T2, CONT2> const &);
};
//#include "Stack.h"
template <typename T, template<typename, typename> class CONT>
void Stack<T, CONT>::push(T const & elem)
{
elems.push_back(elem);
}
template <typename T, template<typename, typename> class CONT>
void Stack<T, CONT>::pop()
{
if(elems.empty())
{
//cout << "Stack empty!!!\n";
return ;
}
elems.pop_back();
}
template <typename T, template<typename, typename> class CONT>
T Stack<T, CONT>::top()const
{
return elems.back();
}
template <typename T, template<typename, typename> class CONT>
template <typename T2, template<typename, typename> class CONT2>
Stack<T, CONT> & Stack<T, CONT>::operator = (Stack<T2, CONT2> const & op2)
{
if((void *)this == (void *)&op2)
return *this;
Stack<T2, CONT2> tmp(op2);
elems.clear();
while(!tmp.empty())
{
elems.push_front(tmp.top());
tmp.pop();
}
return *this;
}
#endif // STACK_H_INCLUDED