#A vector of pointers that are individually deleted

87 messages ยท Page 1 of 1 (latest)

kindred ravineBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

#

@frosty comet

Screenshots!

Your message appears to contain screenshots but no code. Please send code and error messages in text instead of screenshots if applicable!

frosty comet
#

I'm editing the message hold on, sorry

south vale
#

just use std::vector<std::unique_ptr<PlayerProjectile>> instead

#

that way the pointer deletes itself when it leaves scope

#

(or shared_ptr if you need it to be shared)

frosty comet
#

sorry, but how do you push a pointer into a vector like that?

#

and how would you delete one while in a loop through the elements?

#

I don't have much knowledge about unique pointers

kindred ravineBOT
#

@frosty comet

Please Do Not Delete Posts!

Please don't delete forum posts. They can be helpful to refer to later and other members can learn from them. In the future you can use !solved to close a post and mark a post as solved.

frosty comet
#

didn't mean to do that

#

๐Ÿ˜ญ

south vale
#

vec.push_back(std::make_unique<PlayerProjectile>(args, for, PlayerProjectile, go, here))

#

then you don't have to do anything to delete them other than removing them from the vector

#

they will delete themselves if they leave scope

frosty comet
#

can you delete an element from a vector while iterating through?

#

like

#

for (Class class1 : class1es)?

south vale
#

the iterator might become invalidated in certain situations, but i believe it's possible if you use something that returns a new iterator that you can continue from when the deletion happens

#

if i get a sec i can toss an example together

frosty comet
#

thanks

kindred ravineBOT
#

@frosty comet Has your question been resolved? If so, type !solved :)

south vale
#

;compile -std=c++23

#include <memory>
#include <print>
#include <vector>
#include <ranges>
#include <algorithm>

struct PlayerProjectile {
    PlayerProjectile(std::string name, bool delete_me)
        : m_name{ std::move(name) }
        , m_delete_me{ delete_me } 
    {
        std::println("{} Created", m_name);
    }

    ~PlayerProjectile() {
        std::println("{} Destroyed", m_name);
    }

    std::string m_name{};
    bool m_delete_me{};
};

int main() {
    std::vector<std::unique_ptr<PlayerProjectile>> projectiles{};
    
    std::println("Populating vector...");
    projectiles.push_back(std::make_unique<PlayerProjectile>("Projectile 1", false));
    projectiles.push_back(std::make_unique<PlayerProjectile>("Projectile 2", true));
    projectiles.push_back(std::make_unique<PlayerProjectile>("Projectile 3", false));

    std::println("Removing Projectile 2 from vector...");
    const auto [first, last] = std::ranges::remove_if(
        projectiles, [](std::unique_ptr<PlayerProjectile>& proj) { 
            return proj->m_delete_me; 
        });

    projectiles.erase(first, last);

    std::println("Printing remaining items in vector...");
    for (std::unique_ptr<PlayerProjectile>& proj : projectiles)
        std::println("Vector Contains: {}", proj->m_name);
    
    std::println("End of main() scope (vector and all remaining items will be deleted after this)");
}
raven beaconBOT
#
Program Output
Populating vector...
Projectile 1 Created
Projectile 2 Created
Projectile 3 Created
Removing Projectile 2 from vector...
Projectile 2 Destroyed
Printing remaining items in vector...
Vector Contains: Projectile 1
Vector Contains: Projectile 3
End of m
south vale
#

using the remove_if() funcions (either std::ranges::remove_if or std::remove_if) lets you delete items using a custom lambda/callable that takes in an element from the vector and if it returns true, it will be removed from the vector when the first and last locations are passed into vector.erase();

#

the output is a little cut off, but if you click on the "View in godbolt" link, you should see all of it (where the list gets deleted at the very end)

frosty comet
#

how does auto&& work? I thought a reference to a reference is illegal

south vale
#

in this situation, the auto&& is a forwarding reference, but it's also unecessary. it's not a reference to a reference, the && can either represent an r-value or a forwarding reference depending on the context of it's use. for this function, you can just use std::unique_ptr<PlayerProjectile>& in place of the auto&&

#

c++ can get a bit confusing when it comes to that type of stuff though, so i wouldn't worry about it until you reach a point in your learning where it starts to matter

frosty comet
#

I don't really get it, but I'll just sub in what you just said ๐Ÿ˜…

south vale
#

haha yeah, it's a bit confusing until you learn the core syntax/functionality of the language

frosty comet
#

how do lambdas work?

#

just

#

how do you write them, I mean

#
[](what) {
  what
}
south vale
#

i just edited the snippet above so it doesn't use auto&& anywhere btw

#
[captures, go, here](parameters, go, here) {
  // body goes here 
}
frosty comet
#

ok I'll read that instead

south vale
#

that link will go over the essentials

#

yeah theres too much to explain haha

#

the link will be clearer anyway since it's designed to help teach these concepts

#

that website has a ton of good content if you're learning c++

#

i'd recommend using it to learn the core feature set of c++

frosty comet
#

I'm fine with copying some advanced code that I don't understand, as long as it works ๐Ÿ˜† I'll understand it someday

frosty comet
south vale
#

the sooner the better since it'll make any code you try to write a lot easier to understand

#

but copying code is kind of normal early on.. . you really should always try to understand how something works before using it though. if you don't know what it's doing (or how it's doing it), there's always the chance that you use the code incorrectly. at the very least, make sure to debug through code you copy from somewhere else and validate that it's all working correctly

frosty comet
#

how would I delete the current element while looping with for (std::unique_ptr<PlayerProjectile>& proj : projs) rather than with std::remove_if

south vale
#

can you write a snippet of pseudo-code to show exactly what you mean? the remove_if is still iterating through all of the items... it just uses the lambda to determine which items to remove and returns a new iterator that you pass into the vector.erase().

#

the loop is just happening internally instead of directly in the main() function

frosty comet
#
for (std::unique_ptr<PlayerProjectile>& proj : projs) {
    if (proj->deleteMe) {
        
    }
    else proj->Update();
}

that's the current setup I have for checking whether to delete the object, would remove_if be better?

south vale
#

to do that, you'd just change this part from my snippet:

    const auto [first, last] = std::ranges::remove_if(
        projectiles, [](std::unique_ptr<PlayerProjectile>& proj) { 
            return proj->deleteMe; 
        });
#

i'll edit the code above to show you that example

#

just finished making the edits

#

you can see the output of the new code (which is the same as the old output since Projectile 2 is deleted again in this example since m_delete_me is set to true for it.

#

(also, you'd just call proj->Update() for all remaining items in the loop that follows the projectiles.erase(first, last) line)

#

since those would be all of the projectiles that didn't get deleted

frosty comet
#

sorry I deleted that, here it is again.

south vale
#

in the project file, make sure you have c++latest selected as your c++ version

#

then make sure to #include <algorithm> for that function

frosty comet
#

my project was in C++ 14 ๐Ÿ˜ญ

south vale
frosty comet
#

is that the default or something?

south vale
#

yeah i think so

#

this stuff might work with c++20 selected also. i forget if any of it is c++23 specific

frosty comet
#

alr I switched it to 2020 and no errors in the editor

south vale
#

c++23 brings in the std::print() stuff which is a lot nicer than std::cout

frosty comet
#

now I'm gonna run it

south vale
#

๐Ÿ‘

frosty comet
#

oh the build error is

#

just

#

a SYNTAX ERROR

#

yipee

south vale
#

is it a different error than the one you showed above?

frosty comet
#

forgot a semicolon :3

#

it works now lets go

#

thank you so much

#

I've been stuck on this for like

#

idk actually

#

not that long

#

but whatever

south vale
#

haha np, happy to help