欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

模板类的特化和类型萃取

程序员文章站 2022-06-10 15:06:59
...

模板类的特化:

有时为了需要,针对特定的类型,需要对模板进行特化,也就是所谓的特殊处理。

全特化 :对传入的数据类型都做了限制

偏特化(半特化):偏特化并不仅仅是指特殊部分参数,而是针对模板参数更进一步的条件限制所设计出来的一个特化版本。

模板的全特化和偏特化都是在已定义的模板基础之上,不能单独存在。

template <typename T1, typename T2>
class Data
{
public:
	Data()
	{
		cout << "Data<T1, T2>" << endl;
	}
};

template <>
class Data<int , int>
{
public:
	Data()
	{
		cout << "Data<int, int>" << endl;
	}
};

////全特化  >   局部特化   >    无特化版本 ; 匹配最匹配的
//// 模板的全特化和偏特化都是在已定义的模板基础之上,不能单独存在

template <class T>
class Data<T, int>
{
public:
	Data()
	{
		cout << "Data<T, int>" << endl;
	}
};

template <class T1, class T2>
class Data<T1*, T2*>
{
public:
	Data()
	{
		cout << "Data<T1*, T2*>" << endl;
	}
};

template <class T1, class T2>
class Data<T1, T2*>
{
public:
	Data()
	{
		cout << "Data<T1, T2*>" << endl;
	}
};



template <class T1, class T2>
class Data<T1&, T2&>
{
public:
	Data()
	{
		cout << "Data<T1&, T2&>" << endl;
	}
};


void test1()
{
	Data<char, char> d;		//   T    T
	Data<int, char> d1;		//   T    T
	Data<int, int> d2;		//   int int
	Data<char, int> d3;		//    T   int
	
	Data <int*, int*> d4;	//   int*  int*
	Data <int, int*> d5;	//    T    int*
	Data <int&, int&> d6;	//   int&  int&
}

类模板特化的应用:类型萃取

对指定的类型使用特定的处理方式。

模板类的特化和类型萃取

#pragma once

#include <iostream>
#include <string>

using namespace std;

struct __TrueType
{};

struct __FalseType
{};


// POD: plain old data 平凡类型(无关痛痒的类型)--基本类型
// 指在C++ 中与 C兼容的类型,可以按照 C 的方式处理。
template <class T>
struct TypeTraits
{
	typedef __FalseType IsPodType;
};

template <>
struct TypeTraits< bool>
{
	typedef __TrueType IsPodType;
};

template <>
struct TypeTraits<int>
{
	typedef __TrueType IsPodType;
};

template <>
struct TypeTraits<char>
{
	typedef __TrueType IsPodType;
};

template <>
struct TypeTraits<long long>
{
	typedef __TrueType IsPodType;
};

template <>
struct TypeTraits<short>
{
	typedef __TrueType IsPodType;
};

template <>
struct TypeTraits<double>
{
	typedef __TrueType IsPodType;
};

//template <>
//struct TypeTraits<Date>		//Date为自定义类型   ,当我们要用特定的方式处理自定义类型时,也可以这样做
//{
//	typedef __TrueType IsPodType;
//};


template <class T>
inline T* __TypeCopy(const T* src, T* dst, size_t n, __TrueType)		//普通类型(声明了的)  memcpy
{
	cout << "memcpy   " << typeid(T).name() << endl;
	return (T*)memcpy(dst, src, sizeof(T) * n);
}

template <class T>
inline T* __TypeCopy(const T* src, T* dst, size_t n, __FalseType)	//非普通类型    for, 与上面的构成重载
{
	cout << "for + operator=   " << typeid(T).name()<< endl;
	for (size_t i = 0; i < n; i++)
	{
		dst[i] = src[i];
	}
	return dst;
}

template <class T>
inline T* TypeCopy(const T* src, T* dst, size_t n)
{
	return __TypeCopy(src, dst, n, TypeTraits<T>::IsPodType());
}

void TestTypeCopy()
{
	string s1[3] = { "11", "22", "33" };
	string s2[3] = { "" };
	int a1[3] = { 1, 2, 3 };
	int a2[3] = { 0 };
	TypeCopy(s1, s2, 3);
	TypeCopy(a1, a2, 3);
}