C++ template

1.自定义Stack模板类

#include <vector> #include <stdexcept> template <typename T>

class Stack {

  private:

    std::vector<T> elems;     // elements public:

    void push(T const&);      // push element void pop();               // pop element T top() const;            // return top element bool empty() const {      // return whether the stack is empty return elems.empty();

    }

};



template <typename T>

void Stack<T>::push (T const& elem)

{

    elems.push_back(elem);    // append copy of passed elem }



template<typename T>

void Stack<T>::pop ()

{

    if (elems.empty()) {

        throw std::out_of_range("Stack<>::pop(): empty stack");

    }

    elems.pop_back();         // remove last element }



template <typename T>

T Stack<T>::top () const {

    if (elems.empty()) {

        throw std::out_of_range("Stack<>::top(): empty stack");

    }

    return elems.back();      // return copy of last element }

测试

#include <iostream> #include <string> #include <cstdlib> #include "stack1.hpp" int main()

{

    try {

        Stack<int>         intStack;       // stack of ints Stack<std::string> stringStack;    // stack of strings // manipulate int stack intStack.push(7);

        std::cout << intStack.top() << std::endl;



        // manipulate string stack 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;  // exit program with ERROR status }

}



由于多掉了一次pop所以报错

2.用typdef产生一个特定模板类别名

比如Stack<int>

typedef Stack<int> IntStack;

int main()

{

    IntStack intStack;

    intStack.push(7);

    std::cout << intStack.top() << std::endl;

}

3.模板类的特化

#include <deque> #include <string> #include <stdexcept> #include "stack1.hpp" template<>

class Stack<std::string> {

  private:

    std::deque<std::string> elems;  // elements public:

    void push(std::string const&);  // push element void pop();                     // pop element std::string top() const;        // return top element bool empty() const {            // return whether the stack is empty return elems.empty();

    }

};



void Stack<std::string>::push (std::string const& elem)

{

    elems.push_back(elem);    // append copy of passed elem }



void Stack<std::string>::pop ()

{

    if (elems.empty()) {

        throw std::out_of_range

                ("Stack<std::string>::pop(): empty stack");

    }

    elems.pop_back();         // remove last element }



std::string Stack<std::string>::top () const {

    if (elems.empty()) {

        throw std::out_of_range

                ("Stack<std::string>::top(): empty stack");

    }

    return elems.back();      // return copy of last element }



基于模板类之上,对于特定类型进行重新实现,比如上面就是一个对std:: string的特例实现,内部用deque实现

测试

#include <iostream> #include <string> #include <cstdlib> #include "stack2.hpp" int main()

{

    try {

        Stack<int>         intStack;       // stack of ints Stack<std::string> stringStack;    // stack of strings // manipulate int stack intStack.push(7);

        std::cout << intStack.top() << std::endl;

        intStack.pop();



        // manipulate string stack 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;  // exit program with ERROR status }

}

上面Stack<std::string>使用了特化的类

4.局部特化

若模板类有两个参数,那么确定其中一个参数,另一个未确定的话,则可以说是局部特化

image

这些概念与c#的泛型是相同的.

5.预设模板

与局部特化概念差不多,但保留了参数,给参数设置了一个默认的类型

#include <vector> #include <stdexcept> template <typename T, typename CONT = std::vector<T> >

class Stack {

  private:

    CONT elems;               // elements public:

    void push(T const&);      // push element void pop();               // pop element T top() const;            // return top element bool empty() const {      // return whether the stack is empty return elems.empty();

    }

};



template <typename T, typename CONT>

void Stack<T,CONT>::push (T const& elem)

{

    elems.push_back(elem);    // append copy of passed 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();         // remove last element }



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();      // return copy of last element }



示例:这样如果用默认的类型,就可以少指定一个模板类的类型

#include <iostream> #include <deque> #include <cstdlib> #include "stack3.hpp" int main()

{

    try {

        // stack of ints: Stack<int> intStack;



        // stack of doubles which uses a std::deque<> to manage the elements Stack<double,std::deque<double> > dblStack;



        // manipulate int stack intStack.push(7);

        std::cout << intStack.top() << std::endl;

        intStack.pop();



        // manipulate double stack 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;  // exit program with ERROR status }

}



你可能感兴趣的:(template)