Yeah it’s not completely seamless. IDK if there’s a possible fix. That’s just C++.
Unless there’s something about C++ I don’t know. But I’m also sure epic would’ve figured that out.
Yeah it’s not completely seamless. IDK if there’s a possible fix. That’s just C++.
Unless there’s something about C++ I don’t know. But I’m also sure epic would’ve figured that out.
This has nothing to do with C++. The error is coming from UnrealHeaderTool, which is entirely under their control. Epic is just enforcing the best practice laid out in the documentation for TObjectPtr that it shouldn’t be used as a function parameter or return. They can’t do anything about functions that aren’t reflected, which is why the error only shows up for UFUNCTIONs.
With 5.5 and 5.6 they’ve added a lot more implicit conversions between raw pointers and TObjectPtr. As well as implicit conversions between containers of them. There should be fewer and fewer reasons to write functions (even unreflected ones) that take those types.
Guys, is it just me or TObjectPtr does not treat const-correctness properly?
UPD: I was wrong, please skip this post
I am currently using UE 5.6 and I recently had an error (“Array has changed during ranged-for iteration!”) with this code:
for (const auto& C : Capsule->GetAttachChildren()) {
if (C == LyingCapsuleHelper)
continue;
C->AddRelativeLocation(Offset, false, nullptr, ETeleportType::TeleportPhysics);
}
The problem was that AddRelativeLocation was triggering some actor overlaps, which resulted in a detachment of its controller, which resulted in modification of Capsule.AttachedChildren field. Which is exactly the field that is returned by the AttachChildren() method:
const TArray<TObjectPtr<USceneComponent>>& USceneComponent::GetAttachChildren() const
{
return AttachChildren;
}
You can see that this method returns a const reference to the array, so I guess the developers’ intent was to prevent me from accidently modifying the contents. When I iterate over the const array in my code, I get const member references (C has the type const TObjectPtr<USceneComponent>&). But this does not prevent me from calling the non-const method AddRelativeLocation(). Why? Because TObjectPtr::operator→() is defined as following:
T* operator->() const
{
return Get();
}
It returns T* rather than const T*. I don’t think it’s correct.
You are confusing the const-ness of the array with the const-ness of the contents. The pointers themselves would be const (because they are the array elements). However they are not const pointers, so they can still be used to mutate what they point at.
(Examples use raw pointers for simplicity but it’s the same if you use TObjectPtr instead)
const TArray< USceneComponent* >- In this case, Array is const so you can’t add or remove elements directly to it. This could either be because it’s a reference to something like in your example or an input or just constructed to be immutable. However, the SceneComponents in the array are not const, so can be mutated.
TArray< const USceneComponent* > - The array is now mutable (can call Add/Remove/etc) but the component elements themselves can’t be modified.
const TArray< const USceneComponent* >- Both the array itself and the contents of the array are immutable.
This is a common difficulty when using C++.
My bad, should have checked it myself with std::vector before posting ![]()