如何将std :: queue转换为std :: vector

Ant*_*ony 6 c++ queue std stdvector

我需要使用双精度队列,因为它具有作为有序容器的良好属性.我想将此队列传递给接受向量的类构造函数.如果我直接这样做,我会收到以下错误:

候选构造函数不可行:第二个参数没有已知的从'std :: queue'到'std :: vector&'的转换

如何将队列强制转换为向量?

Cin*_*out 8

我认为没有任何直接的方法可用。因此,这可以通过将元素一个一个地添加到向量来实现。

std::vector<int> v;
while (!q.empty())
{
    v.push_back(q.front());
    q.pop();
}
Run Code Online (Sandbox Code Playgroud)

请注意,此后队列将为空。

正如@David 在评论中所建议的,最好避免复制队列元素(尤其是当包含的对象很大时)。使用emplace_back()withstd::move()来实现相同的效果:

v.emplace_back(std::move(q.front()));
Run Code Online (Sandbox Code Playgroud)

  • 你可能想要**移动**从 `q.front()` 返回的对象,而不是复制它们:`v.emplace_back(std::move(q.front()));`。尽管如此,你得到了我的赞成,因为这是唯一实际可行的答案 (2认同)

Ric*_*ges 8

用于模拟queue_like行为和类似矢量行为的正确容器是a std::deque.

这具有以下优点:

  1. 在双端队列的两端进行恒定时间的插入和删除

  2. 能够在不破坏双端队列的情况下迭代元素

std::deque支持begin()end()方法,这意味着您可以直接构造向量(具有兼容的值类型).

#include <vector>
#include <deque>

class AcceptsVectors
{
public:
  AcceptsVectors(std::vector<double> arg);
};

int main()
{
    std::deque<double> myqueue;

    auto av = AcceptsVectors({myqueue.begin(), myqueue.end()});
}
Run Code Online (Sandbox Code Playgroud)

a的非变异转换queue为a vector是不可能的.


Ami*_*ory 5

std::vector有一个构造函数接受一对迭代器,所以如果你能够遍历队列,你将被设置.

借用这个问题的答案,您确实可以通过子类化来实现std::queue:

template<typename T, typename Container=std::deque<T> >
class iterable_queue : public std::queue<T,Container>
{
public:
    typedef typename Container::const_iterator const_iterator;

    const_iterator begin() const { return this->c.begin(); }                                                                               
    const_iterator end() const { return this->c.end(); }
};
Run Code Online (Sandbox Code Playgroud)

(注意我们只允许const迭代;为了问题的目的,我们不需要允许修改元素的迭代器.)

有了这个,很容易构建一个vector:

#include <queue>
#include <vector>

using namespace std;

template<typename T, typename Container=std::deque<T> >
class iterable_queue : public std::queue<T,Container>
{
public:
    typedef typename Container::const_iterator const_iterator;

    const_iterator begin() const { return this->c.begin(); }                                                                               
    const_iterator end() const { return this->c.end(); }
};

int main() {
    iterable_queue<int> int_queue;
    for(int i=0; i<10; ++i)
        int_queue.push(i);

    vector<int> v(int_queue.begin(), int_queue.end());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)