1.函数模板

//普通与模板同时存在的时候,优先使用普通函数
int Max(int a, int b)
{
    return a > b ? a : b;
}
template <typename _Ty>
_Ty Max(_Ty a, _Ty b)
{
    return a > b ? a : b;
}

class MM {
    friend ostream& operator<<(ostream& out, const MM& obj);
public:
    MM(string name, int age) :name(name), age(age) {}
    bool operator>(MM object)
    {
        return this->age > object.age ? true : false;
    }
protected:
    string name;
    int age;
};
ostream& operator<<(ostream& out, const MM& obj)
{
    out << obj.name << "\t" << obj.age << endl;
    return out;
}
//类中的成员函数为模板
class Test {
public:
    template<class _Ty>
    void print(_Ty data) {
        cout << data << endl;
    }
};

int main()
{
    cout << Max("张三", "李四") << endl;            //隐式调用
    cout << Max<string>("张三", "李四") << endl;    //显示调用

    MM mm1("小可爱", 12);
    MM mm2("小宝贝", 9);

    cout << Max(mm1, mm2) << endl;

    Test t;
    t.print("小甜心");

    return 0;
}

2.类模板

/*
    类模板: 类中用到未知类型
    1.必须显式调用
    2.所有用到类名的地方都是: 类名<未知类型的> 的方式使用
*/
template<class _Ty>
class MM {
public:
    void print();
    void print2() {
        cout << "Hello" << endl;
    }
protected:
    static int num;
};

template<class _Ty>
int MM<_Ty>::num = 0;

template<class _Ty>
void MM<_Ty>::print()
{
    cout << "类模板" << endl;
}
template<class _Ty>
class Girl :public MM<_Ty>
{

};

template <class _Ty1, class _Ty2>
class Test
{
public:
    Test(_Ty1 first, _Ty2 second) :first(first), second(second)
    {
    }
    void print()
    {
        cout << first << "\t" << second << endl;
    }
protected:
    _Ty1 first;
    _Ty2 second;
};

struct Score
{
    int english;
    int math;
    int py;
    Score(int english, int math, int py)
        :english(english), math(math), py(py) {}
};
ostream& operator<<(ostream& out, const Score& object)
{
    out << object.english << "\t" << object.math << "\t" << object.py;
    return out;
}
void testFunc()
{
    Test<string, int> test(string("李四"), 18);
    test.print();
    Test<string, string> *test1=new Test<string,string>(string("小可爱"), string("小宝贝"));
    test1->print();

    Test<string, Score>* pScore = new Test<string, Score>("小美",
        Score(88, 18, 99));
    pScore->print();
}
//类模板的特化
template <class T1, class T2, class T3>
class A
{
public:
    void print()
    {
        cout << "原版模板" << endl;
    }
protected:

};
//局部特化:局部特化是把类型特殊化,还是一个未知类型
template <class T1>
class A<T1, T1, T1>
{
public:
    void print()
    {
        cout << "局部特化" << endl;
    }
protected:
};
//完全特化: 所有未知类型具体化
template <>
class A<string, int, char>
{
public:
    void print()
    {
        cout << "完全特化" << endl;
    }
protected:
};
void testAObject()
{
    A<string, string, string> a;    //局部特化
    a.print();
    A<string, string, char> b;        //原版特化
    b.print();
    A<string, int, char> c;            //完全特化
    c.print();
}
//类模板不是一个真正类,所以,不可以在多文件中分开写
//声明和实现必须写在一起

int main()
{
    MM<int> mm;
    MM<int>* pmm = new MM<int>;

    //testFunc();
    testAObject();
    return 0;
}