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.
87 messages ยท Page 1 of 1 (latest)
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
Your message appears to contain screenshots but no code. Please send code and error messages in text instead of screenshots if applicable!
I'm editing the message hold on, sorry
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)
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
@frosty comet
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.
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
can you delete an element from a vector while iterating through?
like
for (Class class1 : class1es)?
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
thanks
@frosty comet Has your question been resolved? If so, type !solved :)
;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)");
}
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
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)
how does auto&& work? I thought a reference to a reference is illegal
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
I don't really get it, but I'll just sub in what you just said ๐
haha yeah, it's a bit confusing until you learn the core syntax/functionality of the language
i just edited the snippet above so it doesn't use auto&& anywhere btw
[captures, go, here](parameters, go, here) {
// body goes here
}
ok I'll read that instead
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++
I'm fine with copying some advanced code that I don't understand, as long as it works ๐ I'll understand it someday
nice I'll look at it in the future
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
how would I delete the current element while looping with for (std::unique_ptr<PlayerProjectile>& proj : projs) rather than with std::remove_if
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
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?
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
sorry I deleted that, here it is again.
in the project file, make sure you have c++latest selected as your c++ version
then make sure to #include <algorithm> for that function
my project was in C++ 14 ๐ญ
is that the default or something?
yeah i think so
this stuff might work with c++20 selected also. i forget if any of it is c++23 specific
alr I switched it to 2020 and no errors in the editor
c++23 brings in the std::print() stuff which is a lot nicer than std::cout
๐
is it a different error than the one you showed above?
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
haha np, happy to help