15

I am looking to copy the entire contents of a vector into a queue in C++. Is this a built in function or is it nessesary to loop over each element?

Bill Cheatham
  • 11,396
  • 17
  • 69
  • 104

3 Answers3

22

If you make a new queue, you can use the constructor:

std::vector<int> v = get_vector();

std::queue<long int, std::deque<long int>> q(std::deque<long int>(v.begin(),
                                                                  v.end()));

(You can change the underlying container to taste, though deque is probably the best.)

If the queue already exists, there's no range-based algorithm, though, you can easily write your own:

template <typename Iter, typename Q>
push_range(Q & q, Iter begin, Iter end)
{
    for ( ; begin != end; ++begin)
        q.push(*begin);
}

As an aside: If your algorithm requires that amount of flexibility, you're probably better of just using a std::deque in the first place. The container adapters (queue and stack) should only be used if you want to say explicitly, "this is the behaviour I want" (i.e. push/pop).

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • OP is asking about `queue`, not `deque`. – Björn Pollex Nov 17 '11 at 13:54
  • 1
    In a generic algorithm I would always prefer `++begin` to `begin++` as it avoids a potentially (depending on `Iter::value_type` in this case) expensive copy, even though it makes the code three lines longer. – Björn Pollex Nov 17 '11 at 14:58
  • 2
    @BjörnPollex: Nope, same line count :-) Thanks again! – Kerrek SB Nov 17 '11 at 14:59
  • I'm on C++17 and the queue construction can be simplified to `std::queue q(std::deque(v.begin(), v.end()));`, or even `std::queue q(std::deque(v.begin(), v.end()));`, if you don't need the `long int`. – luizfls May 01 '20 at 16:18
11

Probably the best way is to directly push elements into the queue.

std::vector<T> v;
...
std::queue<T> q;
for (const auto& e: v)
  q.push(e);

Even using std::copy is tedious since you have to wrap the queue in an adapter (Insert into an STL queue using std::copy).

log0
  • 10,489
  • 4
  • 28
  • 62
  • 1
    True, but depends what one wants. I had a situation where given a vector, I wanted to turn it into a queue (not even that -- I only needed the pop method without actually removing elements). Also, I didn't want to copy the elements (every millisecond mattered). In such a situation, it is much easier to simply implement one's own simple queue that takes as an argument the given vector. The rest is trivial. –  Apr 20 '16 at 02:25
2

The queue's constructor is as follows:

explicit queue ( const Container& ctnr = Container() );

So you can have some vector v and construct a queue from it.

vector<int> v;
deque<int> d;
/* some random magic code goes here */
queue<int, deque<int>> q(d(v));

However you can't do this to push_back elements in an already initialized q. You could use another Container, empty your queue, append your vector to that container, and create a new queue from that vector; but I'd iterate rather than doing all that.

Final answer: No, there is no such method implemented for queues, you could use deque or iterate your vector.

Goodwine
  • 1,658
  • 1
  • 18
  • 31
  • Using a vector as underlying datastructure for a queue might not be the best idea, performance-wise. – Christian Rau Nov 17 '11 at 14:20
  • I thought it was possible to do it this way, but the main problem is that you would not be able to `pop` elements since the underlying container must implement `pop_font()`. – log0 Nov 17 '11 at 14:27
  • Then you would have to make a queue from a deque from a vector, that is why I would rather iterate. – Goodwine Nov 17 '11 at 14:38