没看过虚幻的代码,不过看名字和行为来猜,应该是用来检测POD的.
POD是C++中一个无比重要的概念,也是一个非常容易被忽略的概念,每个类都应该有责任和方法告知类的使用者本类是否为POD类.那么如何告知呢? C++11中完全可以使用std::is_pod<> ,或者
std::is_trivial<> 来检测,但是或许是没有C++11或者处于另外的考虑,有时候我们自己也可以想个其他办法来检测POD,虚幻这种方法我还是第一次见,我猜,在代码深处的某个地方肯定有这样一个模板定义:
template<typename T> class TIsPODType;
然后,每增加一个类,比如你举得例子FPlane,我就特化一个TIsPODType<>,特化成:
TIsPODType<FPlane>
然后用一个enum来告知它是不是POD就行了.
//--------------------------------------------------------------------
至于什么是POD呢? 我觉得在C++中POD的最大意义是这说明它的构造和析构是平凡的(trivial),
平凡的构造函数意味着这个构造函数什么都不做,比如一个int(); 或者一个 float(); 只是占一下内存,
构造函数本身不做任何事. 对于拷贝构造函数来说,POD的拷贝构造函数意味着 完全可以使用memcpy的方法构造一个副本. 为什么POD如此重要? 因为假如你有个类:
class Array { public: Array() { p=new int[100]; } ~Array() { delete[] p; } private: int* p; };
这个类显然不是POD,也不是平凡的,如果你使用memcpy的方法创建它的副本,那么就会出现很恐怖的事情: 同一段内存被两个指针指向,会被delete[]两次:
Array a; Array b=a;//你完了
可是,我们经常需要以memcpy的方式来拷贝构造,尤其是使用模板容器时,比如这个容器:
template<typename T> class SuperArray { public: SuperArray() { ptr=new int[10]; size=10; counter=0;} ~SuperArray() { delete[] ptr; } void add(const T& t) { if(counter>=size) { int* temp=new int[size+1]; memcpy(temp,ptr,size); delete[] ptr; ptr=temp; ++size; } ptr[counter++]=t; } private: T* ptr; size_t size; size_t counter; };
当SuperArray内部的内存片不够用时,就重新new一个更长的(先别管效率了..),然后memcpy
老的内存片过来,这种技巧是常用的. 那么这时SuperArray就需要一种检测,检测某个类是否为POD.
如果是,memcpy就成立,如果不是就不成立.
//-----------------------------------
hyphen lee问说为什么不用static变量来存,一方面占空间,还有就是static变量不能当模板参数,这就导致了一些模板处理时的麻烦,例如有一个函数:
template<typename T> void PODcopy(const T& a,const T& b);
假设这是个对两个同类型POD进行拷贝的函数,内部就是简单的memmove,memcpy什么的,那么
它只对POD起作用.那么,这时候就有必要使用IsPOD来进行一些安全方面的保障,重新声明一下:
template<typename T> using enable_me_if_Im_POD = std::enable_if<IsPOD<T>::value>::type template<typename T> void PODcopy(const T& a,const T& b,enable_me_if_Im_POD*=nullptr);
这时,当你使用对两个非POD的类的对象进行PODcopy函数时,就会报错,因为根据"Substitution Failure Is Not An Error",PODcopy的所有非POD类型特化时都会由于enable_if而失败,于是便"隐藏"起来.
同理的还有其他一些好处,所以总的来说使用enum比static变量要好些