前言:
模板也能传入非类型,可用来代替宏;
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
template<size_t N = 10,class T = int>
class test
{
public:
test(const T& a)
{
cout << N << " " << a << endl;
}
private:
T arr[N];
};
int main()
{
test<100, char> a('d');
}
一、函数模板
1.1如自定义类型建立的模板一样函数也可以有模板
比自定义类型的模板不一样的是自定义class test类在实例化时即使test的模板做了全缺省模板也必须要在test后跟<>才可以编译;
template<class T>
T add(T a, T b)
{
return a > b;
}
int main()
{
//test<100, char> a('d');
cout << add(10, 1) << endl;;
cout << add<double>(10.1, 1.2) << endl;;
}
1.2函数模板的特化
和函数重载有些相似,在实例化调用函数时函数会找到最匹配自己的特化
template<class T>
void add(const T& a,const T& b)
{
cout << "this is T" <<endl;
}
template<>
void add<char>(const char& a, const char& b)
{
cout << "this is char" <<endl;
}//函数特化
template<class T>
int main()
{
//test<100, char> a('d');
add(10, 10);
add('a', 'b');
}
输出结果
可知如果有去全特化的函数会有先走全特化函数:add(‘a’,‘b’);没有匹配的特化才会走原本的模板函数进行实例化;
注意函数没有偏特化;
值得注意的是函数对指针进行特化时:
template<class T>
void add(const T& a,const T& b)
{
cout << "this is T" <<endl;
}
template<>
void add<char*>( char*const & a, char*const& b)
{
cout << "this is char" <<endl;
}//函数特化(对指针)
写成char*const & a而不是const char* & a的原因是在标准化下的const修饰的是a这个变量是他本身不可以改变,只有char*const &a,const修饰的才是a本身, const char* & a修饰的是*a也就是指针的指向数据,与const T& a不同所以会发生找不到标准化模板;
二、自定义类型模板
自定义模板新增了偏特化即:只特化参数的一部分
template<class T1, class T2>
class Data
{
public:
Data() { cout << "Data<T1, T2>" << endl; }
private:
T1 _d1;
T2 _d2;
};
template <class T1>
class Data<T1, int>
{
public:
Data() { cout << "Data<T1, int>" << endl; }
private:
T1 _d1;
int _d2;
};//自定义模板类的偏特化
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
Data() { cout << "Data<T1*, T2*>" << endl; }
private:
T1 _d1;
T2 _d2;
};
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:
Data(const T1& d1, const T2& d2)
: _d1(d1)
, _d2(d2)
{
cout << "Data<T1&, T2&>" << endl;
}
private:
const T1& _d1;
const T2& _d2;
};
int main()
{
Data<double, int> d1;
Data<int, double> d2;
Data<int*, int*> d3;
Data<int&, int&> d4(1, 2);
return 0;
}
Data<double, int> d1; // 调用特化的int版本
Data<int, double> d2; // 调用基础的模板
Data<int *, int*> d3; // 调用特化的指针版本
Data<int&, int&> d4(1, 2); //调用特化的引用版本
强调一下
模板函数模板自定义类型不能声明和定义分离(会很麻烦)非要分离必须在定义处显式实例化对象:template
void func(const int a);且是在主页中用一次func的不同模板生成的func你就要实例化一次,不然在程序链接的情况下会链接不通过程序找不到地址;
// math_utils.hpp
#pragma once
template<typename T>
T add(T a, T b); // 仅声明
// math_utils.cpp
#include "math_utils.hpp"
// 定义
template<typename T>
T add(T a, T b) {
return a + b;
}
// 显式实例化
template int add<int>(int, int); // 显式实例化 int 版本
template double add<double>(double, double); // 显式实例化 double 版本

被折叠的 条评论
为什么被折叠?



