模板分类
类模板
类中有些需要参数类型是变化的
template<class T>
class complex
{
public:
complex(T r, T i): re(r), im(i){}
private:
T re;
T im;
}
complex<double> c(1.2, 2.3);
函数模板
函数中的类型是变化的
template<class T>
const T& min(const T& t1, const T& t2)
{
return t1 < t1 ? t1 : t2;
}
class Person
{
public:
Person(int a):age(a)
{
}
bool operator <(const Person& p) const
{
return age < p.age;
}
private:
int age;
};
函数模板中不需要指明具体的模板参数类型,因为c++可以 参数推导
成员模板
模板类中的一部分本身又是template,是可变的类型。很多标准库是这样实现的。
template<class T1, class T2>
class pair
{
public:
template<class U1, class U2>
pair(const pair<U1, U2>& p):first(p.first), second:(p.second)
{
}
private:
T1 first;
T2 second;
};
比如class derived 1: public class base1 lass derived2: public class base2 pair<base1, baise2> p(pair<derived1, derived2>()); 子类赋值给父类的操作是可以且合理的。 标准库中shared_ptr 也是如此实现的。
模板特化 偏特化
针对某种类型的特化。绑定模板某个部分叫特化。
template<class key>
struct hash
{
};
template<>
struct hash<int>
{
};
偏特化,实际上是局部特化。可以个数上或者范围上特化。
个数上
模板中的前几个泛化的类型被绑定为固定的类型
template<class T1, class T2>
class myArray
{
};
template<class T2>
class myArray<bool, T2>
{
};
范围上
当泛化的类型,被先限定为范围更小的类型的时候适用,比如下面的第二个myArray 只适用于指针类型的模板
template<class T1, class T2>
class myArray
{
};
template<class T1, class T2>
class myArray<T1 *, T2 *>
{
};
模板模板参数
模板的泛化类型包括了另外一个模板,比如:
template<class T,
template<class T> class container >
class myArray
{
private:
container<T> c;
};
使用的时候,myArray<std::string, list> mylist;
ps:会报错,list需要第二个模板,虽然有默认,但编译也无法通过
template <class T>
using Lst = list<T, allocator<T>>;
myArray<std::string, Lst> mylist;
非类型模板
模板中的类型为固定类型,比如标准库中的bitset<size_t SIZE> ,此时每个bitset<2> bitset<3> 等等都是不同的类型。适用于一些多种长度不一的场合,比如下述自定义的带size的string,使用的时候更多的节省空间
template<size_t SIZE>
class SizedString
{
public:
SizedString();
SizedString(const char* value);
}
template<size_t SIZE>
SizedString<SIZE>::SizedString()
{
memset(m_value, ' ', SIZE);
}
template<size_t SIZE>
SizedString<SIZE>::SizedString(const char* value)
{
copyValue(value);
}
template <size_t SIZE>
void SizedString<SIZE>::copyValue(const char* value)
{
size_t i = 0;
for (; i < SIZE && value[i] != '\0'; i++) {
m_value[i] = value[i];
}
for (; i < SIZE; i++) {
m_value[i] = ' ';
}
}
函数中使用的时候,节省空间
struct CabinClass {
utils::SizedString<33> m_id;
utils::SizedString<4> m_recType;
utils::SizedString<4> m_carrierCode;
utils::SizedString<10> m_filler1;
}
下面是定义的copy模板
template<size_t SIZE>
void copy2(char* to, const utils::SizedString<SIZE>& from)
{
strncpy(to, from.data(), from.length());
}
|