Dynamic 2D Array using TArray

Maybe I’m just completely missing the point here and there’s a better way to do this. I’m trying to get a pretty simple dynamically sized 2D array of custom types. This is so close, but the response is not dynamic and I haven’t really found anything else that gets at this specific problem. In normal C++ I’d do something like

vector<vector<myClass>> myVect;

and that would allow me to do what I want. My searching indicates that TArray is the most similar to a vector but I keep getting errors when I try to do something like this:

TArray<TArray<myClass>> myArray;

Since this isn’t working, is there a “best practice” in Unreal that I’m not familiar with, or is there something else I’m missing? I also find it weird that Visual Studio isn’t giving me any red squigglies, it’s only when I compile that I’m made aware of the problem.

In case it helps, this is the actual error log:

CompilerResultsLog:Error: Error d:\program files\epic games\4.14\engine\source\runtime\core\public\Containers/Array.h(1745) : error C2248: 'ATile::ATile': cannot access private member declared in class 'ATile'
CompilerResultsLog:Error: Error c:\users\user\documents\unreal projects\sneakysnake\source\sneakysnake\public\Tile.h(11) : note: see declaration of 'ATile::ATile'
CompilerResultsLog:Error: Error c:\users\user\documents\unreal projects\sneakysnake\source\sneakysnake\public\Tile.h(9) : note: see declaration of 'ATile'
CompilerResultsLog:Error: Error d:\program files\epic games\4.14\engine\source\runtime\core\public\Containers/Array.h(1771) : note: see reference to function template instantiation 'int32 TArray<ATile,FDefaultAllocator>::Emplace<ATile>(ATile &&)' being compiled
CompilerResultsLog:Error: Error d:\program files\epic games\4.14\engine\source\runtime\core\public\Containers/Array.h(1771) : note: see reference to function template instantiation 'int32 TArray<ATile,FDefaultAllocator>::Emplace<ATile>(ATile &&)' being compiled
CompilerResultsLog:Error: Error d:\program files\epic games\4.14\engine\source\runtime\core\public\Containers/Array.h(1771) : note: while compiling class template member function 'int32 TArray<ATile,FDefaultAllocator>::Add(ATile &&)'
CompilerResultsLog:Error: Error C:\Users\user\Documents\Unreal Projects\SneakySnake\Source\SneakySnake\Private\WorldGen.cpp(24) : note: see reference to function template instantiation 'int32 TArray<ATile,FDefaultAllocator>::Add(ATile &&)' being compiled
CompilerResultsLog:Error: Error C:\Users\user\Documents\Unreal Projects\SneakySnake\Source\SneakySnake\Private\WorldGen.cpp(21) : note: see reference to class template instantiation 'TArray<ATile,FDefaultAllocator>' being compiled

all the rest of the codz can be found here.

tl;dr: I want a dynamic 2d array and TArray is giving me lots of errors. What’s the correct way to do this?

Hi dlkulp,

I believe I saw this issue before and the solution was to place the secondary TArray in a USTRUCT like the following;

USTRUCT()
struct FEncapsule
{
TArray<MyClass> Foo;
}

TArray<FEncapsule> MyArray;

To let it behave more like a default array, you can override the [] operator for the FEncapsule struct.

Hope this helps. Cheers,

1 Like

I think you want:

TArray<TArray<ATile*>> levelMap;

You can’t have containers of UObject values, only UObject pointers. However, as mentioned by project.gheist, you probably also want to wrap the inner array in a USTRUCT() and then make levelMap a UPROPERTY(), as this will allow garbage collection to work correctly for your map.

Steve

Your override was a great idea! I just wanted to add this for other peoples reference:

USTRUCT()
struct FRune2DArray{
	GENERATED_BODY()
public:

	TArray<FRune> Ar;

	FRune operator[] (int32 i) {
		return Ar[i];
	}

	void Add(FRune rune) {
		Ar.Add(rune);
	}
};

I needed a 2D array for my FRune structs, so by overriding [] and adding an Add function (and any other you want) you can perfectly simulate a real 2D Tarray. Here is the result:

	TArray<FRune2DArray> runes;

	runes.Add(FRune2DArray());
	runes.Add(FRune2DArray());

	runes[1].Add(FRune());
	
	runes[1][0]; //contains the FRune I just added
6 Likes

how would i do this if i was making a 2d for an actor class. it is for an inventory system