The Cast function is only for UObject types - TArray isn’t a UObject, so you shouldn’t use Cast on it.
TArray is not a standard container, so doesn’t have begin/end member functions. It does have begin/end non-member functions so that it can be used in ranged-for loops (e.g. for (auto Actor : CollectedActors)), but these are not intended to be called directly.
std::move is fine, but the UE equivalent is MoveTemp. However, it wouldn’t work in either case because you can’t move between container types of different types.
The reinterpret_cast method wouldn’t require that you check against nullptr, unless the array already contains nullptrs, which it shouldn’t do in your example case.
Fundamentally, TArray (and in general, C++) does not support type covariance. C++ does a limited form support return type covariance of overridden virtual functions, but that’s not applicable here.
I’d recommend going with what Jamie wrote except that I’d do this:
for(AActor* Actor : CollectedActors)
{
ABatteryPickup* batteryPickup = static_cast<ABatteryPickup*>(Actor);
/** Your code */
}
… because the GetOverlappingActors function guarantees that the all of the Actors returned are of the right type, so you don’t need the safety (slowness) of Cast.
Cast makes it safer for code maintenance, because if the surrounding code evolves such that non-ABatteryPickup objects somehow get added to your array then you will get null pointers instead of illegal pointers. However, if that is a future concern then you should add a null check too:
for(AActor* Actor : CollectedActors)
{
ABatteryPickup* batteryPickup = Cast<ABatteryPickup>(Actor);
if (batteryPickup)
{
/** Your code */
}
}
Steve