Announcement

Collapse
No announcement yet.

TMap with struct

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    TMap with struct

    The example code for TMap using structs isn't working. I am talking about the code here at the bottom of the page.

    If you use the code from the example, you will get the error:
    Code:
    Unrecognized type 'FMyStruct' - type must be a UCLASS, USTRUCT or UENUM
    So if I make the struct a USTRUCT I will receive the error:
    Code:
    USTRUCTs are not currently supported as key types.
    Is it so that the documentation is outdated and there is no way to use structs?

    #2
    I also have trouble following the documentation page, it seem to target more advanced use-cases thus require the using the BaseKeyFuncs template.

    What I needed is just a simple map however, and after some heavy Google-ing I at least got my TMap that uses a USTRUCT as key to compile, just by overriding the ==operator and GetTypeHash().
    Note I only got it to compile and I still need more testing to check if everything is working ok.

    Here are the methods I defined inside my USTRUCT:

    bool operator==(const FMyStruct& s) const
    {
    // return your == definition
    }

    friend FORCEINLINE uint32 GetTypeHash(const FMyStruct& s)
    {
    //return your hash definition
    }

    Would also like to know from more experienced users whether what I done above is correct, thanks.

    Comment


      #3
      Here is short sample for USTRUCT() used as Key in TMap<>

      Code:
      USTRUCT()
      struct FMyStruct
      {
       GENETERATED_USTRUCT_BODY()
      
       int32 ID;
      
       bool operator== (const FMyStruct& Other)
       {
         return int32 ID == Other.ID;
       }
       friend uint32 GetTypeHash (const FMyStruct& Other)
       {
         return GetTypeHash(Other.ID);
       }
      }
      This should work. You can replace int32 with any hashable type, which can be converted to numeric value. Like FName.
      https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

      Comment


        #4
        I am still getting
        Code:
        USTRUCTs are not currently supported as key types.

        Comment


          #5
          Originally posted by ChillyFlashER View Post
          I am still getting
          Code:
          USTRUCTs are not currently supported as key types.
          mind posting the full code of the struct?

          Comment


            #6
            This isn't the exact code I am using, but this still wont compile.

            Code:
            USTRUCT()
            struct FMyStruct
            {
            	GENERATED_BODY()
            
            	int32 ID;
            
            	bool operator== (const FMyStruct& Other)
            	{
            		return ID == Other.ID;
            	}
            
            	friend uint32 GetTypeHash(const FMyStruct& Other)
            	{
            		return GetTypeHash(Other.ID);
            	}
            };
            
            UCLASS()
            class AActorTest : public AActor
            {
            	GENERATED_BODY()
            
            	UPROPERTY(VisibleAnywhere)
            	TMap<FMyStruct, int32> hashmap;
            };
            Code:
            ActorTest.h(30) : USTRUCTs are not currently supported as key types.

            Comment


              #7
              Originally posted by ChillyFlashER View Post
              This isn't the exact code I am using, but this still wont compile.

              Code:
              USTRUCT()
              struct FMyStruct
              {
              	GENERATED_BODY()
              
              	int32 ID;
              
              	bool operator== (const FMyStruct& Other)
              	{
              		return ID == Other.ID;
              	}
              
              	friend uint32 GetTypeHash(const FMyStruct& Other)
              	{
              		return GetTypeHash(Other.ID);
              	}
              };
              
              UCLASS()
              class AActorTest : public AActor
              {
              	GENERATED_BODY()
              
              	UPROPERTY(VisibleAnywhere)
              	TMap<FMyStruct, int32> hashmap;
              };
              Code:
              ActorTest.h(30) : USTRUCTs are not currently supported as key types.
              Have you tried using GENERATED_USTRUCT_BODY() instead of GENERATED_BODY() for your struct? I know they "replaced" GENERATED_UCLASS_BODY() with GENERATED_BODY() but I'm not sure if the macro is meant to be used for USTRCTs too.

              Off-topic: This is the one thing that I hate most for UE4, many things have been deprecated / changed since release but the internet is flooded with legacy use cases / information while there is not a central place that can verify what is currently correct. (there is the source-code but I think its not realistic for an average user to dig through it on every aspect...)

              Comment


                #8
                I tried using GENERATED_USTRUCT_BODY() , does not change anything.

                FYI: GENERATED_UCLASS_BODY() doesn't creates the constructor, GENERATED_BODY() does.

                I never thought of going into the source code for something this simple, even when there is a documentation page.
                So I did a search for TMap and found this great example.

                This is the code I came up with that works.
                Code:
                struct FMyStruct
                {
                	int32 ID;
                
                	FMyStruct()
                	{}
                
                	friend bool operator==(const FMyStruct& first, const FMyStruct& second)
                	{
                		return (first.ID == second.ID);
                	}
                };
                
                UCLASS()
                class AActorTest : public AActor
                {
                	GENERATED_BODY()
                
                	//UPROPERTY(VisibleAnywhere)
                	TMap<FMyStruct, int32> hashmap;
                };
                Having a UPROPERTY() on the TMap doesn't work apparently, it will throw the USTRUCT issue again.

                Comment


                  #9
                  You can definitely have UPROPERTY() on TMaps, but not UPROPERTY(VisibleAnywhere) :-)

                  Main purpose to use empty UPROPERTY() would be to prevent garbage collection if your values or keys have pointers to other UObjects..
                  • Follow me on twitter
                  • Visit our website traverse.world
                  • Checkout our game's forum thread

                  Comment


                    #10
                    Originally posted by xulture View Post
                    You can definitely have UPROPERTY() on TMaps, but not UPROPERTY(VisibleAnywhere) :-)

                    Main purpose to use empty UPROPERTY() would be to prevent garbage collection if your values or keys have pointers to other UObjects..
                    If I have UPROPERTY() , I get the error:
                    Code:
                    Unrecognized type 'FMyStruct' - type must be a UCLASS, USTRUCT or UENUM

                    Comment


                      #11
                      ahh that's because of the struct as key.. otherwise TMaps can be UPROPERTY()
                      • Follow me on twitter
                      • Visit our website traverse.world
                      • Checkout our game's forum thread

                      Comment


                        #12
                        Reflection system does not support TMap, so don't place UPROPERTY(), you need to use USTRUCT() if you using structure as argument in function, because reflection system need to see structure in order for function argument to work in reflection system
                        =========
                        My Tutorials:
                        Basic knowledge about Classes and UObject environment and stuff like that

                        Comment


                          #13
                          TMap is exposed to reflection since 4.7 .
                          https://github.com/iniside/ActionRPGGame - Action RPG Starter kit. Work in Progress. You can use it in whatever way you wish.

                          Comment


                            #14
                            I had the same problem and none of the answers here helped me really. I searched a while in the internet but couldn't get something run for me so I looked in the unreal source code and I found out how I can solve my problem.
                            I searched for "uint32 GetTypeHash(" and the first header with it was AssetEditorSelectedItem.h from unreal source code. I found out that I had to write a function in my struct with a
                            uint32 GetTypeHash() const
                            {
                            // write your hash generation here
                            (I found some hash generation in FCrc.h if you need a hash generation)
                            }
                            body. Outside the USTUCT I had to implement a function with
                            FORCEINLINE uint32 GetTypeHash(const 'structname'& other)
                            {
                            return other.GetTypeHash();
                            }

                            that's for the hash, the function with
                            bool operator==(const 'structname'& other) const
                            {
                            }
                            worked for me fine.
                            I know this post is really outdated but I hope my answer can help.

                            Comment

                            Working...
                            X