Another STL question

Started by
23 comments, last by Fruny 17 years, 11 months ago
Quote:why not just put the data in a vector and a iterator do the removing? wouldn't that be much more efficient?

The thing is that my dataholders point directly to each other as part of their data. So when I need to remove a dataholder that I have arrived at from another dataholder, I won't have an iterator to work with.

Quote:Now, as for your function, what is the behavior when the object on which it is called is the last item in the list? Maybe there's more to it (a sentinel object, or perhaps some code you left out)

Yeah, presently I have a sentinel object at each end of my doubly linked list which are never removed.
Advertisement
What is the exact purpose of your Dataholder class? Is there any reason why you cannot directly store the objects in the containers -- even as pointers? Could you not substitute iterators in place of your Dataholders?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:
Is there any reason why you cannot directly store the objects in the containers -- even as pointers? Could you not substitute iterators in place of your Dataholders?

I'm not sure I understand these questions. Perhaps my problem would be more clear if you considered this:
class Dataholder{  public:    int data;    Dataholder* otherDataholder;    void remove();}

Now say I need to delete otherDataholder. The variable otherDataholder cannot be of iterator type because the iterator won't get updated if I move otherDataholder from one list to another.
What I mean is why don't you do std::list<int> data; or std::list<int*> data; and completely get rid of the Dataholders? What is the precise role of Dataholder in your framework?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
honestly, i'm not understanding the problem with you using vectors and iterators
//granted all pseudocodevector list1 = {1, 2, 3, 4, 5, 6, 7};vector list2 = { };iterator move = list1.front;for (move; move != list1.end; ++move) {     list2.insert(move);}move = list1.front;move.moveTo(4); //move to 4th element in vector move.remove; //takes the data at this position in the vector and deletes it.

granted someone correct me if i'm wrong but isn't this how iterators and vectors work in STL?

Beginner in Game Development?  Read here. And read here.

 

Quote:
What is the precise role of Dataholder in your framework?

Ok, it's a space partitioning scheme. Each Dataholder is a partition. They have pointers to their neighbours. And I need to have more than one list of partitions.
I see. I need to think about it. Can a partition belong to several lists or only one?
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Each partition only belongs to one list (anything else would be horrid to work with). Actually, I only have two lists: One for partitions with moving objects within, and one for those without. The partitioning is updated every frame.

Zahlmans code absolutely solved the problem as stated, but not fast enough for my purpose.

I've considered using arrays, but that entails a whole host of other issues. I've also cosidered a Factory class to memory manage my partitions, which might be a good idea, but regardless, I don't see a way around my own list implementation.
Quote:Original post by Wiggin
Each partition only belongs to one list (anything else would be horrid to work with). Actually, I only have two lists: One for partitions with moving objects within, and one for those without. The partitioning is updated every frame.

Zahlmans code absolutely solved the problem as stated, but not fast enough for my purpose.


Oh. Well, that makes things MUCH clearer then. :)

Don't move things about between two lists at all. Instead, partition a single list, remembering (by storing an iterator) where one partition ends and the next begins. (Yeah, partitioning a list of partitions... oh dear, name overload!)

#include <algorithm>#include <list>bool hasMovingObject(const Partition& p) {  // logic here...}class World {  // ...  std::list<Partition> partitions;  std::list<Partition>::iterator firstWithoutMovingObjects;  // ...  void update() {    // ...    // Re-partition the list    firstWithoutMovingObjects = std::partition(partitions.begin(),                                                partitions.end(),                                                hasMovingObject);    // ...    updatePartitionsWithMovingObjects(partitions.begin(),                                       firstWithoutMovingObjects);    updatePartitionsWithoutMovingObjects(firstWithoutMovingObjects,                                          partitions.end());    // ...  }};


Quote:
I've considered using arrays, but that entails a whole host of other issues.


The best part about the standard library algorithms is that you are insulated against changes to your container types (given a few careful typedefs). They even work on plain arrays :)
I guess the lesson here is not to oversimplify ones problem when asking for help.

I think I'm beginning to see the light... almost.

So when I add a partition with no moving object, I append it, and when I add a partition with, I prepend it, and the iterator firstWithoutMovingObjects will remain valid, right? That's fairly nifty.

What about when I, due to objects moving out of the area, need to delete some smaller partitions and replace them with a bigger one? In this case, I have access to the partitions via their pointers to neighbours, so I don't have iterators to work with, and it still seems I need to search through the list to find them.

This topic is closed to new replies.

Advertisement