0

Basically I need to be able to use operations like push_back() + random access a list like std::vector is able to do, while also keeping its pointer validity, like std::list does. Is this possible?

I was working with pointers pointing to various elements inside the list, and while std::vector provides random access to elements, everything invalidates upon push_back().

cafce25
  • 15,907
  • 4
  • 25
  • 31
Ramster445
  • 45
  • 5
  • 1
    You might want a [std::deque](https://en.cppreference.com/w/cpp/container/deque) ETA no you don't that invalidates iterators. Hmmm. – Nathan Pierson Apr 27 '23 at 01:23
  • How "set in stone" are the requirements? Can you duplicate data? – Ted Lyngmo Apr 27 '23 at 01:26
  • 1
    Use indexes rather than iterators? – Avi Berger Apr 27 '23 at 01:31
  • I can, but its not ideal since i want to run these operations often @TedLyngmo – Ramster445 Apr 27 '23 at 01:33
  • 5
    If you know the vector will not grow beyond a certain size, then you can `reserve()` that size up front and then know that your `push_back` operations will not invalidate iterators (except `end()`), provided you do not exceed the initial capacity. – paddy Apr 27 '23 at 02:50
  • 1
    @paddy You should write that as the answer: _Yes_ it is possible, _iff_... – Dúthomhas Apr 27 '23 at 03:08
  • A solution that retains good cache performance is a bucket array. The idea is that the data is stored in self-contained buckets (arrays) which never move in memory. Additionally, a master array containing pointers to all buckets is kept to ensure O(1) random access. If the last bucket is full, a new bucket is allocated and added to the master bucket array (which can just be a std::vector since its pointer stability is irrelevant). The compromise is that removing items must be limited in one way or another. – dialer Apr 29 '23 at 11:27

2 Answers2

1

Perhaps you have heard of a data structure like a hash-linked list? This data structure is an extension of the linked list, which maintains an additional array on top of the normal linked list, the number of elements of this array is the same as the number of elements of the linked list, except that its elements are pointers to the corresponding linked list elements. The advantage of this data structure is that it allows for random access and makes use of fragmented memory. But this seems to be some deviation from your problem description? I'm not sure if this would meet your needs..

Code just like this(I'm very sorry, I had very little time to write the answer so I didn't really compile and run it, maybe the code is still buggy, hahaha):

#include <list>
#include <vector>

templete<typename T>
class CHashList
{
public:
  std::list<T> m_data;
  std::vector<T*> m_pointer;
public:
  void push_back(T newData)
  {
    m_data.push_back(newData);
    m_pointer.push_back(&m_data.back());
  }
  T& operation[](int i)
  {
    return *m_pointer[i];
  }
  // other operations...
};

Hope it can help you.

DreamerX
  • 49
  • 6
0

Boost's stable_vector gives a ready solution for what you ask.

From its documentation:

Like vector, iterators are random access. stable_vector does not provide element contiguity; in exchange for this absence, the container is stable, i.e. references and iterators to an element of a stable_vector remain valid as long as the element is not erased.

cafce25
  • 15,907
  • 4
  • 25
  • 31
vvv444
  • 2,764
  • 1
  • 14
  • 25