UE4中的 TIsIntegral 和 TIsVoidPointer
作者: PP屁屁
TIsIntegral
/**
* Traits class which tests if a type is integral.
*/
template <typename T>
struct TIsIntegral
{
enum { Value = false };
};
template <> struct TIsIntegral< bool> { enum { Value = true }; };
template <> struct TIsIntegral< char> { enum { Value = true }; };
template <> struct TIsIntegral<signed char> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned char> { enum { Value = true }; };
template <> struct TIsIntegral< char16_t> { enum { Value = true }; };
template <> struct TIsIntegral< char32_t> { enum { Value = true }; };
template <> struct TIsIntegral< wchar_t> { enum { Value = true }; };
template <> struct TIsIntegral< short> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned short> { enum { Value = true }; };
template <> struct TIsIntegral< int> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned int> { enum { Value = true }; };
template <> struct TIsIntegral< long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long> { enum { Value = true }; };
template <> struct TIsIntegral< long long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long long> { enum { Value = true }; };
template <typename T> struct TIsIntegral<const T> { enum { Value = TIsIntegral<T>::Value }; };
template <typename T> struct TIsIntegral< volatile T> { enum { Value = TIsIntegral<T>::Value }; };
template <typename T> struct TIsIntegral<const volatile T> { enum { Value = TIsIntegral<T>::Value }; };
实现还是挺有趣的。
这其实是一直很常用的利用特化实现功能的方法,因为是在编译期实现,所以性能也是杠杠的。
分析:
摘取第一部分
TIsIntegral 不看其他代码,只看以下代码
template <typename T>
struct TIsIntegral
{
enum { Value = false };
};
TIsIntegral<T>::Value 不管T输入什么值,char 也好,什么也好,这个匿名枚举在被定义的时候值是 false
加上中间部分
TIsIntegral不看其他代码,只看以下代码
template <typename T>
struct TIsIntegral
{
enum { Value = false };
};
//**************************新加代码
template <> struct TIsIntegral< bool> { enum { Value = true }; };
template <> struct TIsIntegral< char> { enum { Value = true }; };
template <> struct TIsIntegral<signed char> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned char> { enum { Value = true }; };
template <> struct TIsIntegral< char16_t> { enum { Value = true }; };
template <> struct TIsIntegral< char32_t> { enum { Value = true }; };
template <> struct TIsIntegral< wchar_t> { enum { Value = true }; };
template <> struct TIsIntegral< short> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned short> { enum { Value = true }; };
template <> struct TIsIntegral< int> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned int> { enum { Value = true }; };
template <> struct TIsIntegral< long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long> { enum { Value = true }; };
template <> struct TIsIntegral< long long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long long> { enum { Value = true }; };
//**************************新加代码
- 加了新加代码的相当于在 TIsIntegral<T>::Value 中的 T 输入 bool / char / signed char 等等的时候,这个匿名枚举在被定义时候,Value 值为 true
- 其他情况为 False
TIsIntegral全部代码
template <typename T>
struct TIsIntegral
{
enum { Value = false };
};
template <> struct TIsIntegral< bool> { enum { Value = true }; };
template <> struct TIsIntegral< char> { enum { Value = true }; };
template <> struct TIsIntegral<signed char> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned char> { enum { Value = true }; };
template <> struct TIsIntegral< char16_t> { enum { Value = true }; };
template <> struct TIsIntegral< char32_t> { enum { Value = true }; };
template <> struct TIsIntegral< wchar_t> { enum { Value = true }; };
template <> struct TIsIntegral< short> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned short> { enum { Value = true }; };
template <> struct TIsIntegral< int> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned int> { enum { Value = true }; };
template <> struct TIsIntegral< long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long> { enum { Value = true }; };
template <> struct TIsIntegral< long long> { enum { Value = true }; };
template <> struct TIsIntegral<unsigned long long> { enum { Value = true }; };
//**************************新加代码
template <typename T> struct TIsIntegral<const T> { enum { Value = TIsIntegral<T>::Value }; };
template <typename T> struct TIsIntegral< volatile T> { enum { Value = TIsIntegral<T>::Value }; };
template <typename T> struct TIsIntegral<const volatile T> { enum { Value = TIsIntegral<T>::Value }; };
//**************************新加代码
- 以下三行相当于在碰到 T 为 const T/ volatile T/ const volatile T情况下
- 把上面 const / volatile / const volatile 去掉 ,把T单独输入到 TIsIntegral<T>::Value 中
- 相当于递归定义,再把 TIsIntegral<T>::Value 的值赋给 TIsIntegral< const / volatile / const volatile T>::Value
TIsVoidPointer
分析:
TIsIntegral全部代码
这次实现虽然是和上面差不多的功能,但是这个的实现就很有C11的风格了
//顾名思义
//TIsVoidPointer通过模板特化来在编译期检测一个指针是不是void*,而不是int*或者是其他的什么东西
template <typename T> struct TIsVoidPointer { static constexpr bool Value = false; };
template <> struct TIsVoidPointer< void*> { static constexpr bool Value = true; };
template <> struct TIsVoidPointer<const void*> { static constexpr bool Value = true; };
template <> struct TIsVoidPointer< volatile void*> { static constexpr bool Value = true; };
template <> struct TIsVoidPointer<const volatile void*> { static constexpr bool Value = true; };
和上面实现方式类似,但是不是用枚举,而是用静态的变量去表示
TIsVoidPointer::Value其实是可以取址的,每一个特化都会分配一个bool的内存。
而TIsIntegral不可以
他们出现的目的:
我们看一个简单的例子
template<typename T,bool Judge>
struct TestStruct
{
};
template<>
struct TestStruct<int,true>
{
public:
static constexpr int HelloIntAndTrue = 1;
};
template<>
struct TestStruct<int, false>
{
public:
static constexpr int HelloIntAndFalse = 1;
};
- 我们可以通过
TestStruct<int,true>::HelloIntAndTrue
TestStruct<int,false>::HelloIntAndFalse - 来针对同一个结构体,不同参数定义不一样的行为。
- 我们想实现一个需求:
在原有的基础上,增加一个如果T是int变量,我们就定义HelloIntAndTrue,否则定义HelloIntAndfalse
- 我们结合TIsIntegral改造一下
template<typename T,bool Judge = TIsIntegral<T>::Value>
struct TestStruct
{
};
template<>
struct TestStruct<int,true>
{
public:
static constexpr int HelloIntAndTrue = 1;
};
template<>
struct TestStruct<int, false>
{
public:
static constexpr int HelloIntAndFalse = 1;
};
是不是一目了然
#结束