Vector of queue pointers

I am wondering if someone could tell me if it is possible to set up a vector of queue pointers (using STL containers) and how I would go about doing this. I am new to using STL containers, and I'm having trouble figuring out how I would access each vector, and in turn, how I would access each queue. I want to use the vector to store multiple queues.


How would I go about setting this up and inserting a numerical value into the first queue located at the first position in the vector?



Is there a particular design reason why it needs to be pointers instead of just complete objects? If they are pointers, who is responsible for the memory?

But to answer your question, something like...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <queue>

using namespace std;

int main()
{
    queue<int> q1;
    vector<queue<int>*> queues;
    
    queues.push_back(&q1);
    queues[0]->push(42);
    
    // Access first element of first queue
    cout << queues[0]->front() << '\n';
}


... how I would access each vector
I assume you mean, each vector element? Vectors can be indexed in O(1) time with the operator[], but queues can't.
Last edited on
Ganado,
containers of pointers can be very powerful. Not talking dynamic memory, but say you had a large data list or tree of data and the user needs to sort it a variety of ways .. By name, by number, and by city or something like that. If you had a container of pointers back to the real data, like a vector, you can re-sort it each way efficiently (just sorting the pointers, swapping only integers internally) whereas the full objects are heavy to copy/swap etc. Same for loading up a queue ... if the queue is just managing existing items for something, like a task list of known tasks (go 200 yards, turn left, go 200 yards, turn left, ...) or whatever you can just have a queue of pointers back to the hard objects and its lighter/faster/etc.

'Tacos, If this is going to involve dynamic memory... maybe tell us what you want to do exactly before you design an out of control monster... :)
I agree! But it requires a good reason, like what you said. It was only a question to make sure Tacos had a good reason.
> Not talking dynamic memory, but say you had a large data list or tree of data and the user
> needs to sort it a variety of ways .. By name, by number, and by city or something like that.
> If you had a container of pointers back to the real data, like a vector, you can re-sort it each way efficiently

C++ offers several ways to refer to the objects in the original sequence - reference wrappers, pointers, iterators, and with a sequence that supports random access, indices. A container of pointers is not the only (or often, even the best) way of doing that.
For example, using reference_wrappers: https://www.cplusplus.com/forum/general/108632/#msg590747
Agreed. I will probably always mentally equate references and pointers but I have, over the last year, stopped using pointers when a reference is better. That was very difficult for me. I have sort of made peace with iterators, but its still an uneasy peace!
Last edited on
Thanks everybody, I appreciate the insight/advice. I am not very familiar with using STL containers, so this is quite the learning curve. :)

“... how I would access each vector
I assume you mean, each vector element?”

Ganado, yes, that’s exactly what I meant, thank you for clarifying.

“'Tacos, If this is going to involve dynamic memory... maybe tell us what you want to do exactly before you design an out of control monster... :)”

Jonnin,
So, the example I used was intended to help me understand how I would go about this using something simple like integers. In my actual project, I would be passing in an object by reference. Without getting bogged down by details, I had a project for school that I partially completed by the due date. Now that the due date has passed, I wanted to go back and work on this as an exercise (just for my own edification).

Regarding using dynamic memory: In other parts of my project where I used a vector pointer, I added an iterator to my destructor to deallocate the memory. I have not attempted this yet with a vector of queue pointers, so I’m not entirely sure of how I’m going to approach it. This is how I did it in other parts of my project. Example where vector is of type, "Sports", and called "teams", my destructor would contain the following:
1
2
3
4
5
for(vector<Sports*>::iterator it = teams.begin();it != teams.end(); it++)
{
delete *it;
}
 


Ok. Its fine to do this to learn. As you study the STL more, you will see why you don't need to do pointers and dynamic memory very often: the containers do it for you, and clean up for you.

or, to say it plainly: its very likely that a vector of queues will solve the same problem, instead of queue pointers. If you are already partly done etc keep going, but when you are done, think on that again, see if you understand whether the pointers were actually, really necessary or not.
Slightly more 'c++ish' would be a vector of queue iterators.

The main issue with storing pointer/iterator is making sure that they remain valid. so changes to the underlying queue which would effect the pointer/iterator needs to be also reflected in the vector.
Thank you , Jonnin. Pointers have often been the bane of my existence, so I'm glad I won't have to use them too often in the real world.

Seeplus, "changes to the underlying queue which would effect the pointer/iterator needs to be also reflected in the vector." Can you explain what this means, or do you have a brief example that would demonstrate what this looks like in practice?
> Pointers have often been the bane of my existence, so I'm glad I won't have to use them too often in the real world.

You do not have to use something ugly (something very "C++98ish") here like a queue of iterators either. I do not have a clear idea of what you are trying to achieve, but this may give you some ideas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <vector>
#include <list>
#include <functional>
#include <queue>

struct sports
{
    int id = 0 ;
    // etc.
};

// make it lessthancomparable
bool operator< ( const sports& a, const sports& b ) { return a.id < b.id ; }

// we use a list to hold the objects: note that adding or removing elements to/from the list
//                does not invalidate iterators and references to other elements in the list.
std::list<sports> sports_collection ;

// queues hold references to sports which are already in the list
// https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
using queue_type = std::queue< std::reference_wrapper<sports> > ;

// all our queues are kept in a vector holding queues
std::vector<queue_type> vector_of_queues ;

int main()
{
    // usage example

    // add some items to the collection
    for( int v : { 23, 48, 52, 65 } ) sports_collection.push_back( sports{v} ) ;
    // add an empty queue to the vector
    vector_of_queues.emplace_back() ;
    // add references to the elements in the list to that queue
    for( sports& s : sports_collection ) vector_of_queues.back().push(s) ;

    // add another empty queue to the vector
    vector_of_queues.emplace_back() ;
    // add some more items to the collection, and add them to the second queue
    for( int v : { 101, 128, 154, 178, 184, 192 } )
    {
        sports_collection.push_back( sports{v} ) ;
        vector_of_queues.back().push( sports_collection.back() ) ;
    }

    // this is just for illustration: destructively print out the contents of the queues
    for( std::size_t i = 0 ; i < vector_of_queues.size() ; ++i )
    {
        auto& q = vector_of_queues[i] ;
        std::cout << "queue #" << i << " holds references to " << q.size() << " items: [ " ;
        while( !q.empty() )
        {
            std::cout << "sports{" << q.front().get().id << "} " ;
            q.pop() ;
        }
        std::cout << "]\n" ;
    }
}

http://coliru.stacked-crooked.com/a/6dfc0dc1c32ad477
Thanks everyone, you've given me a lot to research and play around with.
Topic archived. No new replies allowed.