UE4中的 TIsIntegral 和 TIsVoidPointer

9 篇文章 0 订阅
3 篇文章 0 订阅

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;
};

是不是一目了然
#结束

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值