C++ Error C2679: Binary '=': no operator found which takes right-hand operand of type 'TArray'

The error points to that line, so assuming it was something in the generated.h file i looked in there for a line where the ‘=’ operator is used and found this

The project compiles if i change it from

to

but everytime i change code in the ARTSHUD class, the generated file gets regenerated and i dont want to have to keep redoing this everytime.

Is this an error im making or is it a problem with unreal?

Any help would be so greatly appreciated as i’ve spent the last 3 days trying to work this out

also another thing to note is that when i change the return type to TArray of UBlueprint* this bug no longer occurs

Id recommend to try changing your return array from UClass* to TSubclassof and updating the function with that in mind.

im using the array to get the CDO of each class and using that to put information into a UMG button so would i still be able to get the CDO from TSubclassof in blueprints?

#Pass by Reference

This would go a lot smoother if you pass the array by reference like this:

//void return type, pass array by reference
void ARTSHUD::GetAllUnitsOfType(Faction, Type, TArray<UClass*>& returnArray)
{
  //current code, but remove the local variable called returnArray
}

now to use it:

  TArray Result;
    GetAllUnitsOfType(EFaction(Faction),EUnitType(Type), Result);

Not sure how you are using your macro but if you are declaring Result somewhere before you use your macro then you dont have to include it in the macro.

#Performance

This setup will have performance benefits for you!

Look up “C++ Return array by reference” to see why.

#Big Picture, Templates

It seems based on your function name that you really want a template function

I suggest template function + GetAllActorsOfClass

I have wikis on both of these subjects.

A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine ForumsObject%26_Actor_Iterators,_Optional_Class_Scope_For_Faster_Search

My solution is based on you wanting to find runtime instances of your units, not entirely sure if that’s your goal or not, if not, then the pass by ref solution should help you :slight_smile:

Enjoy!

Rama

This was the first thing i tried but it gives me the same problem in the generated header :frowning:

What i want to do is get all blueprints in subfolders of the Units folder. i have a menu ingame that has a button for each unit allowing you to call the unit onto the battlefield so i don’t need an instance of the unit just the CDO to get things like the name, the cost, etc. the reason i need the type of unit is because i’m splitting the menu into different menus for each type of unit.

@Rama Since C++11 returning arrays by value should be fine performance wise, the compiler will automatically use move semantics preventing the elements/memory from being copied.
@KieranChandler The error given does appear to be a little strange, but it would seem the reflection system wants you to use TSubclassOf rather than a raw UClass*, as BaderThanBad suggested. This is just a template wrapper around a UClass pointer, so you can use it in exactly the same way.

Thanks @kamrann it compiles now. i think i will have to play around with what class to put in the TSubclassOf template but i think this will work just fine.
i can’t mark your comment as the correct answer so you’ll need to turn it into an answer first Thanks very much for all the help guys @Rama, @BaderThanBad

Did a bit more research, for some reason this error occurs only when using an array of UClass* within a UFUNCTION declaration. All other combinations (such as return an array of some other UObject type, or having a UClass array property) seem to be valid. I’d suggest filing a bug report, I suspect it’s not intentional.

Anyway, for whatever reason, if you use TArray< TSubclassOf< SomeBaseClass > > instead, it seems to work. TSubclassOf is a simple template wrapper around a UClass* which adds a bit more type safety. If you don’t want to restrict the classes which can be assigned to it, then the direct equivalent of UClass* is simply TSubclassOf< UObject >, since UObject is the root of the hierarchy.

Done, with a little extra info.

yeah thats what im doing at the moment but casting to IUnit is failing for some reason. it could be something im doing wrong in the function im trying to work it out at the moment

What fails exactly, casting something to IUnit, or assigning an IUnit* to the TSubclassOf< UObject >? Compile time or run time? And how is the IUnit class declared?

It’s in the screenshot of the code in the original post but i have changed some of the code a bit. the IUnit interface is declared the normal way via c++ and im trying to cast from a blueprint that i have loaded from an asset. the blueprint inherits from ASoldier which inherits from ACharacter and IUnit

Okay I see a few issues, I’ll keep this as a comment since it doesn’t relate to the original question. First, BP->ParentClass would be giving you the UClass representing the BP’s parent, not the BP itself. So the UClass for ASoldier, I guess. Are you sure you don’t want BP->GetBlueprintClass()? Regardless, these are both UClass-derived objects, rather than an ASoldier-derived object, so they don’t implement the interface. You’d need BP->GetBlueprintClass()->GetDefaultObject< ASoldier >() instead, which you should be able to cast to IUnit. But you can’t add this to the return array, since it’s not a UClass. You should add BP->GetBlueprintClass() to the array. Note that BP->GetClass() is definitely not what you want - that just gives the UClass representing the engine class UBlueprint. I hope that makes sense, this stuff can get pretty confusing.

I changed the cast to cast from the UBlueprint pointer to the IUnit pointer and it didnt work but changing the line to a normal c++ cast worked:

i haven’t got the rest of the blueprints finished yet so i cant test this all out yet but if this way doesn’t work i will try that. Yeah i think they should really rename all the getclass functions because its extremely hard to remember which one does what

Yeah i thought it would be dodgy i dont intend to keep it that way though. Thank you for all your help kamrann

You shouldn’t have to use raw C++ casts. That will compile fine but almost certainly crash or anyway not do what you want, since pBlueprint will not be pointing to an IUnit. Anyway hopefully you can sort it, if you have more issues better to open a new question I think.

I cant seem to get it to work the way you said to do it, by doing BP->GetBlueprintClass()->GetDefaultObject< ASoldier >() it returns null and i cannot for the life of me work out how to get from the blueprint to the IUnit functions

Okay it appears GetBlueprintClass() doesn’t do what I expected. Use BP->GeneratedClass->GetDefaultObject() instead (better to leave off the < ASoldier > since I don’t know your exact class hierarchy and you’re just going to cast it to IUnit anyway). Then it would be BP->GeneratedClass which you should add to your array. Hopefully that should work!

Ahhhhh i see! it works with GeneratedClass, i thought that was used with compilation of blueprints like generated headers. everything is good and working now thank you very much again for your help kamrann