美文网首页代码改变世界UE4(虚幻引擎)IT技术分享
UE4随笔——TMap自定义结构体键值

UE4随笔——TMap自定义结构体键值

作者: Jay_Guo | 来源:发表于2017-12-02 15:23 被阅读170次

在UE4中,TMap是一个比较常用的容器,TMap的用法很简单,本文将着重介绍一下TMap如何自定义结构体键值。

UE4随笔

和众多Map容器的实现方法类似,TMap也是通过将Key转换为Hash,来建立对Value的索引,故而想要建立自定义结构体的Key,势必要确保其可顺利转换为Value。下面是UE4中TMap中关于创建Hash的相关代码:

    /** Defines how the map's pairs are hashed. */
    template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
    struct TDefaultMapKeyFuncs : BaseKeyFuncs<TPair<KeyType,ValueType>,KeyType,bInAllowDuplicateKeys>
    {
        typedef typename TTypeTraits<KeyType>::ConstPointerType KeyInitType;
        typedef const TPairInitializer<typename TTypeTraits<KeyType>::ConstInitType, typename TTypeTraits<ValueType>::ConstInitType>& ElementInitType;

        static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
        {
            return Element.Key;
        }
        static FORCEINLINE bool Matches(KeyInitType A,KeyInitType B)
        {
            return A == B;
        }
        static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
        {
            return GetTypeHash(Key);
        }
    };

其中GetSetKey()用于设置Key的值,Matches()用于进行Key值碰撞测试,GetTypeHash()用于获取Key的Hash。根据以上代码不难发现,在生成Hash的时候会会调用Key值结构体的“==”运算符来判断两个Key值是否相等,以及GetTypeHash()来产生Hash,由此我们可以得到第一种构建自定义结构体键值的方法:

struct FMyKey 
{
    FString Name;
    FString Type;

    FORCEINLINE friend bool operator==(const FMyKey& Lhs, const FMyKey& Rhs)
    {
        return (Lhs.Name == Rhs.Name) && (Lhs.Type == Rhs.Type);
    }


};
/** Case insensitive string hash function. */
FORCEINLINE uint32 GetTypeHash(const FMyKey& Key)
{
    return HashCombine(GetTypeHash(Key.Name), GetTypeHash(Key.Type));
}

该方法相当于是写了Key结构体的“==”运算符函数和GetTypeHash函数,它们均为全局函数,这样可以通过我们定义好的全局函数来生成Hash。
第二种方式就是定义自己的MapKeyFuncs来替代TDefaultMapKeyFuncs,代码如下:

struct FMyStruct
{
    // String which identifies our key
    FString UniqueID;

    // Some state which doesn't affect struct identity
    float SomeFloat;

    explicit FMyStruct(float InFloat)
        :UniqueID(FGuid::NewGuid().ToString())
        , SomeFloat(InFloat)
    {
    }
};
template <typename ValueType>
struct TMyStructMapKeyFuncs :
    BaseKeyFuncs<
    TPair<FMyStruct, ValueType>,
    FString
    >
{
private:
    typedef BaseKeyFuncs<
        TPair<FMyStruct, ValueType>,
        FString
    > Super;

public:
    typedef typename Super::ElementInitType ElementInitType;
    typedef typename Super::KeyInitType     KeyInitType;

    static KeyInitType GetSetKey(ElementInitType Element)
    {
        return Element.Key.UniqueID;
    }

    static bool Matches(KeyInitType A, KeyInitType B)
    {
        return A.Compare(B, ESearchCase::CaseSensitive) == 0;
    }

    static uint32 GetKeyHash(KeyInitType Key)
    {
        return FCrc::StrCrc32(*Key);
    }
};
TMap<
    FMyStruct,
    int32,
    FDefaultSetAllocator,
    TMyStructMapKeyFuncs<int32>
> MyMapToInt32;

以上是自己在UE4的学习中总结的两种构造自定义结构体键值的方法,希望对大家能有所帮助。

和众多Map容器的实现方法类似,TMap也是通过将Key转换为Hash,来建立对Value的索引,故而想要建立自定义结构体的Key,势必要确保其可顺利转换为Value。下面是UE4中TMap中关于创建Hash的相关代码:

    /** Defines how the map's pairs are hashed. */
    template<typename KeyType, typename ValueType, bool bInAllowDuplicateKeys>
    struct TDefaultMapKeyFuncs : BaseKeyFuncs<TPair<KeyType,ValueType>,KeyType,bInAllowDuplicateKeys>
    {
        typedef typename TTypeTraits<KeyType>::ConstPointerType KeyInitType;
        typedef const TPairInitializer<typename TTypeTraits<KeyType>::ConstInitType, typename TTypeTraits<ValueType>::ConstInitType>& ElementInitType;

        static FORCEINLINE KeyInitType GetSetKey(ElementInitType Element)
        {
            return Element.Key;
        }
        static FORCEINLINE bool Matches(KeyInitType A,KeyInitType B)
        {
            return A == B;
        }
        static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
        {
            return GetTypeHash(Key);
        }
    };

其中GetSetKey()用于设置Key的值,Matches()用于进行Key值碰撞测试,GetTypeHash()用于获取Key的Hash。根据以上代码不难发现,在生成Hash的时候会会调用Key值结构体的“==”运算符来判断两个Key值是否相等,以及GetTypeHash()来产生Hash,由此我们可以得到第一种构建自定义结构体键值的方法:

struct FMyKey 
{
    FString Name;
    FString Type;

    FORCEINLINE friend bool operator==(const FMyKey& Lhs, const FMyKey& Rhs)
    {
        return (Lhs.Name == Rhs.Name) && (Lhs.Type == Rhs.Type);
    }


};
/** Case insensitive string hash function. */
FORCEINLINE uint32 GetTypeHash(const FMyKey& Key)
{
    return HashCombine(GetTypeHash(Key.Name), GetTypeHash(Key.Type));
}

该方法相当于是写了Key结构体的“==”运算符函数和GetTypeHash函数,它们均为全局函数,这样可以通过我们定义好的全局函数来生成Hash。
第二种方式就是定义自己的MapKeyFuncs来替代TDefaultMapKeyFuncs,代码如下:

struct FMyStruct
{
    // String which identifies our key
    FString UniqueID;

    // Some state which doesn't affect struct identity
    float SomeFloat;

    explicit FMyStruct(float InFloat)
        :UniqueID(FGuid::NewGuid().ToString())
        , SomeFloat(InFloat)
    {
    }
};
template <typename ValueType>
struct TMyStructMapKeyFuncs :
    BaseKeyFuncs<
    TPair<FMyStruct, ValueType>,
    FString
    >
{
private:
    typedef BaseKeyFuncs<
        TPair<FMyStruct, ValueType>,
        FString
    > Super;

public:
    typedef typename Super::ElementInitType ElementInitType;
    typedef typename Super::KeyInitType     KeyInitType;

    static KeyInitType GetSetKey(ElementInitType Element)
    {
        return Element.Key.UniqueID;
    }

    static bool Matches(KeyInitType A, KeyInitType B)
    {
        return A.Compare(B, ESearchCase::CaseSensitive) == 0;
    }

    static uint32 GetKeyHash(KeyInitType Key)
    {
        return FCrc::StrCrc32(*Key);
    }
};
TMap<
    FMyStruct,
    int32,
    FDefaultSetAllocator,
    TMyStructMapKeyFuncs<int32>
> MyMapToInt32;

以上是自己在UE4的学习中总结的两种构造自定义结构体键值的方法,希望对大家能有所帮助。

参考文献:https://www.cnblogs.com/pengyingh/articles/5647879.html

相关文章

  • UE4随笔——TMap自定义结构体键值

    在UE4中,TMap是一个比较常用的容器,TMap的用法很简单,本文将着重介绍一下TMap如何自定义结构体键值。 ...

  • 以太坊(十六)Solidity数据类型-结构体

    自定义结构体 Person就是我们自定义的一个新的结构体类型,结构体里面可以存放任意类型的值。 初始化一个结构体 ...

  • Go 语言程序设计——面向对象编程(5)

    结构体 Go 语言中创建自定义结构体最简单的方式是基于 Go 语言的内置类型创建 自定义类型也可以基于结构体创建,...

  • go-day3

    结构体(struct) 结构体定义 结构体初始化 先声明再赋值 声明同时初始化 键值对初始化 值列表初始化 注意事...

  • Learn Golang In Day 9

    Learn Golang In Day 9 简介 结构体是自定义的数据结构 定义结构体 package main ...

  • C++ 结构体

    结构体简介 结构体是拥护自定义的数据类型,允许用户储存不同的数据类型 语法:struct 结构体名{结构体成员列表...

  • solidity基础(3)

    solidity的自定义结构体深入详解结构体,solidity中的自定义类型,我们可以使用关键字struct来进行...

  • C语言--结构体

    用户可以使用结构体自定义自己的数据类型。 结构体定义和变量声明 struct用来定义结构体,结构体一般定义如下,其...

  • 结构体

    声明:结构体是一种自定义的数据类型 定义: struct 结构体名 变量名 = {初值}; 结构体成员访问: 匿名...

  • 【Golang】json自定义序列化的深入解析

    对于使用结构体中嵌套结构体的情况,只有receiver为指针类型,而嵌套结构体为结构体的值语义的时候不能触发自定义...

网友评论

    本文标题:UE4随笔——TMap自定义结构体键值

    本文链接:https://www.haomeiwen.com/subject/devwbxtx.html