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型別的萃取,貌似依然沒有好的辦法……