struct和class区别
struct:public
class:private
非类型模板参数
注意:
1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2.非类型N传递的是个常量
#include<iostream>
using namespace std;
namespace tt
{
//非类型模板参数--只支持整形
//整形数组
template<class T , size_t N >//非类型模板参数
class Arr
{
private:
T _arr[N];
};
}
int main()
{
tt::Arr<int, 10> arr1;
return 0;
}
模板的特化
注意:特化不能单独存在一定要有原模板
目标:针对某些类型进行特定的特殊化处理
特化意义:将模糊的模板更加精细的细分,以满足更多需求
eg.运输货物。有大型卡车运输煤炭等,小型货车运输零食等,冷藏车运输冷冻食品等。更加精细的分类,能让我们的现实中的运输效率更快,程序同样如此。
全特化:
将所有模糊类中的(template<class T1,class T2>)类型中的T替换成更加精确的具体类型(Date<double, int>)
当传递参数时,能直接识别到<double, int>这样的类型,就去调用类中特殊处理的函数
注意:此处我们只是将上面模糊的类更加精确定义,属于上面类的一种拓展,不需要再定义一次类中的对象
只需要将上述类模板的具体类型和函数内容更改
格式为:
//类模板特化
namespace tt
{
template<class T1,class T2>
class Date
{
public:
Date() { cout << "调用Date<T1,T2>" << endl; }
private:
T1 _a;
T2 _b;
};
//特化类模板--全特化
template<>
class Date<double, int>
{
public:
Date() { cout << "调用Date<double,int>" << endl; }
};
}
int main()
{
tt::Date<int, int> d1;//识别到模糊类调用Date<int, T2>
tt::Date<double, int> d2;
//识别到将此Date类中有更符合的全特化类调用Date<double,int>
return 0;
}
偏特化
将模糊类中的(template<class T1,class T2>)类型中的某个/部分T替换成更加精确的具体类型(Date<int, T2>)
将class T1具体特化成int 此时template<>只有一个T2未特化所以是template<class T2>而Date只特化了T1,T2未特化所以留下T2:Date<int, T2>
格式:
//类模板特化
namespace tt
{
template<class T1,class T2>
class Date
{
public:
Date() { cout << "调用Date<T1,T2>" << endl; }
private:
T1 _a;
T2 _b;
};
//特化类模板--偏特化
template<class T2>
class Date<int, T2>
{
public:
Date() { cout << "调用Date<int, T2>" << endl; }
};
}
int main()
{
tt::Date<int, int> d1;//调用Date<int, T2>
tt::Date<double, int> d2;//调用Date<double,int>
tt::Date<int, double> d3;//调用Date<int, T2>
return 0;
}
那么我们这个精确,只能精确到换参数的类型吗?
这个精确,你能精确到什么程度就能特化到什么程度
eg.指针的特化
//类模板特化
namespace tt
{
template<class T1,class T2>
class Date
{
public:
Date() { cout << "调用Date<T1,T2>" << endl; }
private:
T1 _a;
T2 _b;
};
//特化类模板--全特化
template<>
class Date<double, int>
{
public:
Date() { cout << "调用Date<double,int>" << endl; }
};
//特化类模板--偏特化
template<class T2>
class Date<int, T2>
{
public:
Date() { cout << "调用Date<int, T2>" << endl; }
};
//特化类模板--偏特化--更精确
template<>
class Date<int*, int*>
{
public:
Date() { cout << "调用Date<int*, int*>" << endl; }
};
template<class T1>
class Date<T1, double*>
{
public:
Date() { cout << "调用Date<T1, double*>" << endl; }
};
template<>
class Date<int*, double*>
{
public:
Date() { cout << "调用Date<int*, double*>" << endl; }
};
}
int main()
{
tt::Date<int, int> d1;//调用Date<int, T2>
tt::Date<double, int> d2;//调用Date<double,int>
tt::Date<int, double> d3;//调用Date<int, T2>
tt::Date<int*, int*> d4;//调用Date<int*, int*>
//调用Date<T1, double*>或调用Date<int, T2>
//此时调用的偏特化这两种都可以就会报错
//tt::Date<int, double*> d5;
//正确
tt::Date<double, double*> d5;//调用Date<T1, double*>
tt::Date<int*, double*> d6;//调用Date<int*, double*>
return 0;
}
特殊typename使用
class Date
{
public:
typedef int* address;
Date(int year = 2024) :_year(year) {}
address data() { return &_year; }
private:
int _year;
};
class Time
{
public:
typedef int* address;
Time(int hour = 4) :_hour(new int(hour)) {}
address data() { return _hour; };
private:
int* _hour;
};
template<typename All>
void Myprintf( All& a)
{
//错误
//All::address it = a.data();
//这里的All无法识别用户传来的是什么数据,就不能再去到类里面(内嵌的函数)去取具体的数据
//所以在预编译时未知具体类型不能通过
//加上typename用于标记,先让编译器记住,传来具体实例化的类型再进去使用
//正确
typename All::address it = a.data();
cout << *it << endl;
}
int main()
{
Date d;
Time t;
Myprintf(d);
Myprintf(t);
return 0;
}
使用情况:
只要是在--大模板里面--去取小的类模板--里面的东西就要加 typename,用于让编译器先通过
什么时候实例化?
在传过来具体函数对象类型时