How can I create a TArray<const struct> ? (It won't compile)

I want to create a TArray of const structs, but the compiler is failing on my Add() calls.

Sample code:

USTRUCT(BlueprintType)
struct MULTIPLAYERSESSIONS_API FMultiplayerSessionsSearchResult
{
	GENERATED_BODY()

	FMultiplayerSessionsSearchResult();
	~FMultiplayerSessionsSearchResult();

};

// ...

	auto Results = TArray<const FMultiplayerSessionsSearchResult>();
	Results.Add(FMultiplayerSessionsSearchResult());

And here’s the compiler failure:

2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): error C2665: 'operator new': no overloaded function could convert all the argument types
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Misc\MemStack.h(300): note: could be 'void *operator new(size_t,FMemStackBase &,EMemOned,int32)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,FMemStackBase &,EMemOned,int32)': cannot convert argument 2 from 'std::align_val_t' to 'FMemStackBase &'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Misc\MemStack.h(282): note: or       'void *operator new(size_t,FMemStackBase &,EMemZeroed,int32)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,FMemStackBase &,EMemZeroed,int32)': cannot convert argument 2 from 'std::align_val_t' to 'FMemStackBase &'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Misc\MemStack.h(275): note: or       'void *operator new(size_t,std::align_val_t,FMemStackBase &,int32)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,std::align_val_t,FMemStackBase &,int32)': cannot convert argument 3 from 'const FMultiplayerSessionsSearchResult *' to 'FMemStackBase &'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Misc\MemStack.h(268): note: or       'void *operator new(size_t,FMemStackBase &,int32)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,FMemStackBase &,int32)': cannot convert argument 2 from 'std::align_val_t' to 'FMemStackBase &'
2>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\INCLUDE\vcruntime_new.h(105): note: or       'void *operator new(size_t,std::align_val_t,const std::nothrow_t &) noexcept'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,std::align_val_t,const std::nothrow_t &) noexcept': cannot convert argument 3 from 'const FMultiplayerSessionsSearchResult *' to 'const std::nothrow_t &'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: Reason: cannot convert from 'const FMultiplayerSessionsSearchResult *' to 'const std::nothrow_t'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'std::nothrow_t::nothrow_t': no overloaded function could convert all the argument types
2>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\INCLUDE\vcruntime_new.h(37): note: could be 'std::nothrow_t::nothrow_t(std::nothrow_t &&)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'std::nothrow_t::nothrow_t(std::nothrow_t &&)': cannot convert argument 1 from 'const FMultiplayerSessionsSearchResult *' to 'std::nothrow_t &&'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: Reason: cannot convert from 'const FMultiplayerSessionsSearchResult *' to 'std::nothrow_t'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: Conversion requires a second user-defined-conversion operator or constructor
2>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.38.33130\INCLUDE\vcruntime_new.h(37): note: or       'std::nothrow_t::nothrow_t(const std::nothrow_t &)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'std::nothrow_t::nothrow_t(const std::nothrow_t &)': cannot convert argument 1 from 'const FMultiplayerSessionsSearchResult *' to 'const std::nothrow_t &'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: Reason: cannot convert from 'const FMultiplayerSessionsSearchResult *' to 'const std::nothrow_t'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: Conversion requires a second user-defined-conversion operator or constructor
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: while trying to match the argument list '(const FMultiplayerSessionsSearchResult *)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\ChunkedArray.h(50): note: or       'void *operator new(size_t,TChunkedArray<T,TargetBytesPerChunk,AllocatorType> &)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,TChunkedArray<T,TargetBytesPerChunk,AllocatorType> &)': expects 2 arguments - 3 provided
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\SparseArray.h(39): note: or       'void *operator new(size_t,TSparseArray<T,Allocator> &,int32)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,TSparseArray<T,Allocator> &,int32)': could not deduce template argument for 'TSparseArray<T,Allocator> &' from 'std::align_val_t'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\SparseArray.h(38): note: or       'void *operator new(size_t,TSparseArray<T,Allocator> &)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,TSparseArray<T,Allocator> &)': expects 2 arguments - 3 provided
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(48): note: or       'void *operator new(size_t,TArray<T,AllocatorType> &,TArray<T,AllocatorType>::SizeType)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,TArray<T,AllocatorType> &,TArray<T,AllocatorType>::SizeType)': could not deduce template argument for 'TArray<T,AllocatorType> &' from 'std::align_val_t'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(47): note: or       'void *operator new(size_t,TArray<T,AllocatorType> &)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: 'void *operator new(size_t,TArray<T,AllocatorType> &)': expects 2 arguments - 3 provided
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: while trying to match the argument list '(unsigned __int64, std::align_val_t, const FMultiplayerSessionsSearchResult *)'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2232): note: the template instantiation context (the oldest one first) is
2>I:\Projects\MenuSystem\Plugins\MultiplayerSessions\Source\MultiplayerSessions\Private\MultiplayerSessionsSubsystem.cpp(121): note: see reference to class template instantiation 'TArray<const FMultiplayerSessionsSearchResult,FDefaultAllocator>' being compiled
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2289): note: while compiling class template member function 'int TArray<const FMultiplayerSessionsSearchResult,FDefaultAllocator>::Add(const FMultiplayerSessionsSearchResult &&)'
2>I:\Projects\MenuSystem\Plugins\MultiplayerSessions\Source\MultiplayerSessions\Private\MultiplayerSessionsSubsystem.cpp(123): note: see the first reference to 'TArray<const FMultiplayerSessionsSearchResult,FDefaultAllocator>::Add' in 'UMultiplayerSessionsSubsystem::OnFindSessionComplete'
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2292): note: see reference to function template instantiation 'int TArray<const FMultiplayerSessionsSearchResult,FDefaultAllocator>::Emplace<const FMultiplayerSessionsSearchResult>(const FMultiplayerSessionsSearchResult &&)' being compiled
2>I:\Unreal Engine\UE_5.4\Engine\Source\Runtime\Core\Public\Containers\Array.h(2207): fatal error C1903: unable to recover from previous error(s); stopping compilation

Anyone know of a way to get this to work?

Hi,

try casting it to a const:

Results.Add((const FMultiplayerSessionsSearchResult&)FMultiplayerSessionsSearchResult());

Thanks for the suggestion.

Casting didn’t work, and after replacing the TArray with standard::vector, I got the following compilation error:

The C++ Standard forbids containers of const elements because allocator<const T> is ill-formed.

So looks like containers of const elements are just prohibited in C++.

Interesting - You can use const pointers in TArrays fine but not const inline objects.
Maybe just not have it const?

Yeah in this case I wanted actual structs instead of pointers. Const pointers probably work because the value is const, but the pointer isn’t, so like const int * vs int * const.

This stack overflow explains the issue with const values: c++ - Vector of structs with const members? - Stack Overflow

1 Like

That explains it nicely.