// 函数模板 template<typename T> void tfunc(const T& t) { cout << "template: " << t << endl; } // 函数模板实例化,不用写函数的实现,编译器会生成该类型的模板具体化函数 template void tfunc<char>(const char& c);
类模板
类模板可以指定默认模板参数(函数模板不可以),跟函数参数的默认值一样,必须从右向左连续赋值默认类型,如果实例化对象时又传递了类型,默认类型会被覆盖掉,跟函数参数是一样的
创建对象时需要传递模板参数列表,模板参数列表加在类名后面 ClassName< typename T > classN; 如果类的模板参数列
表有默认值,可以不传模板参数,但一定要加 <> 如 ClassName< > classN; 创建堆区对象的时候,所有的类名称后面都要加模板参数列表,如 ClassName< typename T >* classN = new ClassName< typename T>; 除了类内,其他地方出现 ClassName 的地方一般都要加模板参数列表
template<typename T = int, typename Y = char> // 此处指定了模板默认参数,部分指定必须从右到左指定 class Test { public: Test(T t, Y y) : t(t), y(y) { } void tfunc(); private: T t; Y y; }; template<typename T, typename Y> // 类模板的函数在类外实现,需要加上模板参数列表,但不需要加指定的默认模板参数 void Test<T, Y>::tfunc() { // 类外使用Test需要加模板参数 cout << t << " " << y << endl; } int n = 2; double d = 2.1; Test<int, double> test(n, d); // 此处如果使用默认模板参数可定义为 Test<> test(int(2), char('a')); test.tfunc(); // 运行结果:2 2.1
类模板的继承,类模板被继承后参数的传递方式主要有两种,一种是直接在子类继承父类的时候,为父类指定固定的类型,二是通过子类模板参数列表传递
// ====== 测试一 ====== template<typename T, typename Y> class A { public: A(T t, Y y) { } }; class Test : public A<int, double> { // 父类是类模板,子类是普通类 public: Test() : A<int, double>(2, 2.1) { } }; Test(); // ====== 测试二 ====== template<typename T, typename Y> class A { public: A(T t) { } }; template<typename X, typename Z, typename P> class Test : public A<X, P> { public: Test(X x, Z z, P p) : A<X, P>(x) { } }; Test<int, double, char>(int(2), double(2.1), char('a'));
类模板的多态,在创建对象时,分为子类没有模板(CFather<short, char>*cf = new CSon;)和子类有模板(CFather<short, char> *cf = new CSon<short, int, char>)两种,子类和父类的模板参数列表可以不一样,但一定要对应好
// ====== 测试一 ====== template<typename T, typename Y> class A { public: virtual void tfunc(T t, Y y) = 0; }; class Test : public A<int, double> { public: virtual void tfunc(int n, double d) { cout << n << " " << d << endl; } }; // 父类是类模板,子类是普通类,在多态情况下父类需要指定模板参数,子类就不用了 A<int, double>* a = new Test; a->tfunc(2, 2.1); // 运行结果:2 2.1 // ====== 测试二 ====== template<typename T, typename Y> class A { public: virtual void tfunc(T t, Y y) = 0; }; template<typename X, typename Z, typename P> class Test : public A<X, P> { public: virtual void tfunc(X x, P p) { cout << x << " " << p << endl; } }; // 父类是类模板,子类是类模板,在多态情况下父类和子类都需要指定模板参数 A<int, double>* a = new Test<int, char, double>; a->tfunc(2, 2.1); // 运行结果:2 2.1