功能
类型萃取,在STL中用到的比较多,用于判断一个变量是否为POD类型.
简述来说可以用来判断出某个变量是内置类型还是自定义类型.
通过类型萃取,萃取到变量类型,对不同变量进行不同处理,可以提升程序效率(下面有具体讲解).
应用场景
比如我们实现顺序表,在对顺序表进行扩容时,就靠重新开辟内存、拷贝对象.
拷贝对象时,就有两种情况:一种是类型,比如int char…;还有一种是自定义类型,Data类、String类.
对于内置类型,我们可以通过memset,来进行赋值.(扩展,浅拷贝相关的类也可以通过memset赋值)
而对于自定义类型,大多数深拷贝的对象来说,我们必须通过调用赋值语句来赋值.
因此,我们通常在拷贝对象时,为了不出现错误,都用赋值语句来赋值.
而我们如果有一种方法/机制可以判断POD类型或者非POD类型.
对于POD类型用memset函数,对于非POD用赋值,这样就能提高程序的效率
最大的功能
类型萃取的最大功能就是提高了程序的效率.例如下面的代码,就会出现错误。
template <
class T>
void Copy( T* dst, T* src,size_t size)
{
memcpy(dst, src,
sizeof(T)*size);
}
如果T类型是int,char,float ...这些内置类型,使用memcpy()函数拷贝没有问题,并且使用memcpy()更快,比一个一个赋值赋值语句快很多,但是如果T类型是string这些自定义的类型(有自己的构造函数),使用memcpy()就是出现错误,string通过memcpy()拷贝后,程序就会蹦,因为mencpy()函数是浅拷贝,他只是把string实例化的这个对象的内存拷贝过去,_str浅拷贝过去,当出了这个作用域后,string调用自己的析构函数,因为一块地址被两个指针所指向,析构第二次时就会蹦。 那么解决这个问题的办法就是专门为string写一个拷贝函数,但是这样没有普遍性,写一个类专门写一个函数会很麻烦,模版的类型萃取就很好的解决了这个办法,提高了运算效率,当对象是内置类型是使用mencpy(),当对象是自定义类型时,使用自己写的函数。下面是实现模版的类型萃取的代码。
类型萃取具体实现代码
#pragma once
#include<iostream>
#include<string>
using namespace std;
struct True_Type
{
bool Get_Type()
{
return true;
}
};
struct False_Type
{
bool Get_Type()
{
return false;
}
};
template <
class T>
struct Type_Extraction
{
typedef False_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
int>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
char>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
double >
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
float>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
long long>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
bool>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
unsigned char>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
short>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
unsigned short>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
unsigned int>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
long>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
unsigned long>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
unsigned long long>
{
typedef True_Type Is_Pod_Type;
};
template<>
struct Type_Extraction<
long double>
{
typedef True_Type Is_Pod_Type;
};
template <
class T>
struct Type_Extraction<T*>
{
typedef True_Type Is_Pod_Type;
};
template <
class T>
struct Type_Extraction<
const T*>
{
typedef True_Type Is_Pod_Type;
};
template <
class T>
void Copy( T* dst, T* src,size_t size,True_Type)
{
cout <<
"True_Type" << endl;
memcpy(dst, src,
sizeof(T)*size);
}
template <
class T>
void Copy( T* dst, T* src, size_t size, False_Type)
{
cout <<
"False_Type" << endl;
for (
int i =
0; i < (
int)size; i++)
{
dst[i] = src[i];
}
}
template <
class T>
void Copy( T* dst, T*src, size_t size)
{
if (Type_Extraction<T>::Is_Pod_Type().Get_Type())
{
memcpy(dst, src,
sizeof(T)*size);
}
else
{
for (
int i =
0; i < (
int)size; i++)
{
dst[i] = src[i];
}
}
}
#include<iostream>
#include<string>
#include"test.h"
using namespace std;
int main()
{
string s1[
10] = {
"ad",
"adad",
"adadad" };
string s2[
10] = {
"adadasd",
"adaadadd",
"adadaadadd" };
Copy(s1, s2,
5, Type_Extraction<
string>::Is_Pod_Type());
cout << s1[
1] << endl;
int a[
10] = {
1,
2,
4,
5,
6,
7,
8 };
int b[
10] = {
9,
8,
8,
7,
6,
5, };
Copy(a, b,
5);
cout << a[
0] << endl;
return 0;
}