模板的使用 二

#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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章