POD型别(plain old data),我第一次是在Morden C++ design中看到的。说实话这确实是一本好书,里面的技巧让人叹为观止。里面提到了POD型别,该型别兼容C语言的struct,主要的用处是,POD对象(特别是数组)在进行复制的时候,不必调用对象的复制构造函数或者operator=,可以直接采用memcpy函数来提高效率。Morden C++ design里面讲,可以通过偏特化的方法萃取POD类型,但是没有给出具体的方法,这一直困扰了我好久。
在侯捷对STL源码的剖析中,提到了SGI-STL中对POD型别萃取方式,但是本质上没有通用性。基本的方式是,在某一个类中增加一个typedef,来标识这个类是POD型别,还是不是。实例代码如下:
#include<iostream>
using namespace std;
class A
{
public:
typedef __true_type has_trivial_destructor;
};
class B
{
public:
typedef __false_type has_trivial_destructor;
};
template<class T>
class __traits
{
public:
typedef typename T::has_trivial_destructor has_trivial_destructor;
};
template<class T>
void check(T& t)
{
typedef typename __traits<T>::has_trivial_destructor trivial_destructor;
_check(t,trivial_destructor());
}
template<class T>
void _check(T& t,__false_type)
{
cout<<"Has non-trivial destructor."<<endl;
}
template<class T>
void _check(T& t,__true_type)
{
cout<<"Has trivaial destructor."<<endl;
}
int main()
{
A a;
B b;
check(a);
check(b);
return 0;
}
今天看到了一个方法,让我眼前一亮,它能够编译期确定一个型别是否为POD型别。但是,却不能利用该特性进行型别萃取,只能判断某一型别是否为POD型别,如果不是,编译器报错。方法如下:
template<class T>
struct must_be_pod
{
union
{
T noname;
};
};
将一个类作为模板形参传入,如果其是POD型别,则可以放入union中,否则,不是POD类型。这里其实,是将POD型别等价于可以放入union中的对象。C++中,可以放入union中的对象,是其本身以及其所有的成员变量都没有默认构造函数的对象。
因此,目前对于POD型别的萃取,貌似依然没有好的办法……