如何将 std::queue 转换为 std::vector
How to convert std::queue to std::vector
我需要使用双打队列,因为它作为有序容器具有良好的特性。我想将此队列传递给接受向量的 class 构造函数。如果我直接这样做,我会收到以下错误:
candidate constructor not viable: no known conversion from
'std::queue' to 'std::vector &' for 2nd argument
如何将队列转换为向量?
我认为没有任何直接的方法可用。
因此,这可以通过将元素一个一个地添加到向量中来实现。
std::vector<int> v;
while (!q.empty())
{
v.push_back(q.front());
q.pop();
}
请注意,此后队列将为空。
正如@David 在评论中所建议的那样,最好避免复制队列元素(特别是当包含的对象很大时很有帮助)。使用 emplace_back()
和 std::move()
来达到同样的效果:
v.emplace_back(std::move(q.front()));
std::vector
有一个 constructor taking a pair of iterators,所以如果你能够遍历队列,你就会被设置。
借用 this question 的答案,您确实可以通过子类化 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(); }
};
(注意我们只允许 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;
}
对 queue_like 行为和类似向量的行为进行建模的正确容器是 std::deque
。
这有以下优点:
双端队列两端的恒定时间插入和删除
能够在不破坏双端队列的情况下迭代元素
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()});
}
queue
到 vector
的非突变转换是不可能的。
这只是一种避免将从std::queue
复制到std::vector
的方法。用不用就交给你了
场地
std::queue
是容器适配器。默认情况下,内部 container
为 std::deque
,但您也可以将其设置为 std::vector
。幸运的是,保存这个容器的成员变量被标记为 protected
。因此,您可以通过子类化 queue
.
来破解它
解决方案 (!)
template<typename T>
struct my_queue : std::queue<T, std::vector<T>>
{
using std::queue<T, std::vector<T>>::queue;
// in G++, the variable name is `c`, but it may or may not differ
std::vector<T>& to_vector () { return this->c; }
};
就是这样!!
用法
my_queue<int> q;
q.push(1);
q.push(2);
std::vector<int>& v = q.to_vector();
Demo.
我需要使用双打队列,因为它作为有序容器具有良好的特性。我想将此队列传递给接受向量的 class 构造函数。如果我直接这样做,我会收到以下错误:
candidate constructor not viable: no known conversion from 'std::queue' to 'std::vector &' for 2nd argument
如何将队列转换为向量?
我认为没有任何直接的方法可用。 因此,这可以通过将元素一个一个地添加到向量中来实现。
std::vector<int> v;
while (!q.empty())
{
v.push_back(q.front());
q.pop();
}
请注意,此后队列将为空。
正如@David 在评论中所建议的那样,最好避免复制队列元素(特别是当包含的对象很大时很有帮助)。使用 emplace_back()
和 std::move()
来达到同样的效果:
v.emplace_back(std::move(q.front()));
std::vector
有一个 constructor taking a pair of iterators,所以如果你能够遍历队列,你就会被设置。
借用 this question 的答案,您确实可以通过子类化 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(); }
};
(注意我们只允许 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;
}
对 queue_like 行为和类似向量的行为进行建模的正确容器是 std::deque
。
这有以下优点:
双端队列两端的恒定时间插入和删除
能够在不破坏双端队列的情况下迭代元素
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()});
}
queue
到 vector
的非突变转换是不可能的。
这只是一种避免将从std::queue
复制到std::vector
的方法。用不用就交给你了
场地
std::queue
是容器适配器。默认情况下,内部 container
为 std::deque
,但您也可以将其设置为 std::vector
。幸运的是,保存这个容器的成员变量被标记为 protected
。因此,您可以通过子类化 queue
.
解决方案 (!)
template<typename T>
struct my_queue : std::queue<T, std::vector<T>>
{
using std::queue<T, std::vector<T>>::queue;
// in G++, the variable name is `c`, but it may or may not differ
std::vector<T>& to_vector () { return this->c; }
};
就是这样!!
用法
my_queue<int> q;
q.push(1);
q.push(2);
std::vector<int>& v = q.to_vector();
Demo.