The purpose of using reference in the for loop?

Hi, while I understand the difference between the reference and the pointer, I find the reference in the for loop not making sense to me.

Why do we use reference instead of pointer?

It should be const auto*, see here:

For reasons that take a while to explain, the form of range-based for loop that is the most flexible is:

for (auto&& element : range) {}

This results in element’s type being whatever the type is of the values iterated by range. They will be const if the range is const and they will be rvalues or lvalues based on whether the range returns temporaries or not. The only downside is that it’s hard to actually understand why && works the way it does in this case.

But, I believe it’s explained here. Or at least, if you watch it, things will make much more sense.

How would you integrate const into that expression? It seems that if you write const auto&& then it wouldn’t be the actor that ends up being deduced as const.

Correct, the point of that expression is that it adopts the constness of the elements in the range rather than forcing them to be const.

Unfortuantely, UE4 isn’t really as const correct as their coding style would suggest. For example:

// There's a second, defaulted parameter that I'm ignoring.
void GetOverlappingActors(TArray<AActor*>& OverlappingActors) const;

This really should be:

void GetOverlappingActors(TArray<const AActor*>& OverlappingActors) const;
void GetOverlappingActors(TArray<AActor*>& OverlappingActors);

At least, if you assume that you shouldn’t be able to change actors through a const reference to a UPrimitiveComponent.

The same is true of the GetOwner() function, which is const but returns a non-const AActor.

Once you have that realization, I’m not sure what the point is of trying to make things const in the context of this lesson. UE4 isn’t designed with this sort of constness in mind, so doing it is going to seem unidiomatic, at least in UE4.

You would iterate over a const_cast’d container or similar. There was even a proposal to make for (item : range) to automatically be equivalent to for (auto&& item : range) but it was shot down because it would have introduced a special case of variable declaration.

This only says the function is const, not that the OverlappingActors passed in is.

Why would you want it to return a const object? 9/10 times it should be up to the user not the implementer whether or not they want it const. How would we be able to call GetOwner()->SetActorRotation if GetOwner() returned a const AActor*?

1 Like
void UPrimitiveComponent::GetOverlappingActors(TArray<AActor*>& OverlappingActors) const;

This function signature means that it can be called on a UPrimitiveComponent object which is const. The idea is that functions which are const, do not logically change the object. Sometimes in C++ const is shallow and sometimes deep. In the overlapping actors scenario, it’s not exactly obvious whether a const component should be allowed to change actors which overlap it. My point was that if one were to be conservative, const components wouldn’t be allowed to change actors overlapping the component.

As for the GetOwner() function, that’s basically just a question of idiomatic C++. This would work like this:

const AActor* SomeComponent::GetOwner() const;
AActor* SomeComponent::GetOwner();

So, if you have a non-const component and you call GetOwner(), then you get a non-const AActor. If you have a const component, you get a const AActor.

Make sense?

this lecture needs to stop giving me headaches. I’m sick of figuring this out on my own

hehe don’t worry, you’ll get more (headaches). And then, when it all works, and you understand what you just did, it’s an amazing feeling.

1 Like

the short answer is that you can’t change a reference to an object!.

A pointer is an address to a location on memory, so if you were, for instance, to do something like

MyClass * clsPtr = getMyClassPtr();

for( int ClsCount=; ClsCount < MAGIC_NUM; ClsPtr++)
{
ClsPtr->DoSomething();
}

The compiler will alow you to do it because pointer arrhythmic is valid coding practice, but trying to access ClsPtr would have some pretty disastrous consequences!

Barry

Hello DanM. I have a few problem with TArray:

  1. why the OverLappingActorss is wrong?

  2. I cannot use any method of TArray? why?

  3. I cannot understand logic of the code? How get the object in TArray(OverLappingActorss)?:

    TArray<AActor*> OverLappingActorss;
    PresurePlate->GetOverlappingActors(OUT OverLappingActorss);

In my opinion every object which get in PresurePlate automatically pass to OverLappingActorss. am I right?
and if it’s right why we have OUT ( GetOverlappingActors(OUT OverLappingActorss); ) and what is changing?

1 & 2, you probably don’t have #include "CoreMinimal.h" in your file

3, This is what is talked about, this is an what’s referred to as an output parameter, it’s giving the function an object to be modified within the function

Using normal return value:

int square(int n)
{
    return n * n;
}
int main()
{
    int a = square(2); //a == 4
}

vs output parameter (using references)

void square(int& n)
{
    n * n;
}
int main()
{
    int a = 0;
    square(a); // a == 4
}
  1. & 2. I add #include “CoreMinimal.h” in my header file but problem is not solved. is there any solution?
  1. yes I know about reference. I want to understand logic of the code? how put the object in TArray?
    The aim is that to put only that object in TArray which get in TriggerVolume, isn’t it?
    which function is selecting such object and is putting in TArray? I think it’s
    PresurePlate->GetOverlappingActors(OUT OverLappingActorss); am I right?

Did your errors change?

and yes.

No errors isn’t change

#include "Gameframework/Actor.h"?

No problem is not solved and error is the same
Have you other idea?

Are you reading the output log or the error list. When you compile what errors do you get from the output list?

I don’t understand here is error in Visual Studio:
Error

but Compile form Unreal is successful
I don’t know whats happen?

Privacy & Terms