[英]Insert into an STL queue using std::copy
我想使用std::copy
将元素插入到这样的队列中:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int> q;
copy( v.begin(), v.end(), insert_iterator< queue<int> >( q, q.front() ) );
但这无法编译,抱怨begin
不是std::queue
的成员。
注意:我也用std::inserter
尝试过 - 这也失败了,这次说“reference”不是“std::queue”的成员。 std::back_inserter
和std::back_insert_iterator
也因相同的错误而失败。
我是否遗漏了一些明显的东西,或者insert_iterator
只是不适用于队列?
不幸的是, std::queue
将称为push_back
的函数“改编”为只是push
,这意味着标准back_insert_iterator
不起作用。
可能最简单的方法(尽管在概念上很难看)是用一个寿命短的容器适配器适配器[原文如此](呃!)来适应容器适配器,该适配器与后插入迭代器的寿命一样长。
template<class T>
class QueueAdapter
{
public:
QueueAdapter(std::queue<T>& q) : _q(q) {}
void push_back(const T& t) { _q.push(t); }
private:
std::queue<T>& _q;
};
像这样使用:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
队列不允许迭代其元素。
来自SGI STL 文档:
队列是提供容器功能的受限子集的适配器。队列是“先进先出”(FIFO) 数据结构。 1即元素被添加到队列的后面,可能会从前面移除; Q.front() 是最近加入队列的元素。 队列不允许迭代其元素。 [2]
您可以完成这项工作,但不能使用insert_iterator
。 您必须编写类似queue_inserter
来呈现迭代器接口。
更新我无法自拔并决定尝试实现您需要的迭代器。 结果如下:
template< typename T, typename U >
class queue_inserter {
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q) { }
queue_inserter<T,U> operator ++ (int) { return *this; }
queue_inserter<T,U> operator * () { return *this; }
void operator = (const T &val) { qu.push(val); }
};
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q) {
return queue_inserter<T,U>(q);
}
这适用于这样的功能:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi) {
while (b != e) { *oi++ = *b++; }
}
但它不适用于 STL 副本,因为 STL 是愚蠢的。
std::queue
不是 STL 意义上的容器,它是一个功能非常有限的容器适配器。 对于您似乎需要std::vector
或std::deque
(“双端队列,这是一个“真正的容器”),似乎是正确的选择。
我很确定它不会工作——队列提供push
,但插入迭代器期望使用push_front
或push_back
。 您没有真正的理由不能编写自己的push_insert_iterator
(或您喜欢的任何名称),但这有点痛苦......
insert_iterator
和back_insert_iterator
仅适用于(分别)具有insert
和push_back
方法的容器(或适配器)—— queue
没有这些。 您可以根据这些编写自己的迭代器,如下所示:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
{
public:
explicit push_iterator(Container &c) : container(c) {}
push_iterator &operator*() {return *this;}
push_iterator &operator++() {return *this;}
push_iterator &operator++(int) {return *this;}
push_iterator &operator=(typename Container::const_reference value)
{
container.push(value);
return *this;
}
private:
Container &container;
};
除非这样的东西已经存在,但我很确定它不存在。
您需要的是一个push_inserter
(即执行push
es 到队列中的插入器)。 据我所知,STL 中没有这样的迭代器。 我通常做的是遗憾地回到旧的 for 循环。
如果你有勇气,你可以推出自己的迭代器,大致如下:
template <typename Container>
class push_insert_iterator
{
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
{} // construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
{
//push value into the queue
container.push(v);
return (*this);
}
push_insert_iterator<container_type> & operator*()
{
return (*this);
}
push_insert_iterator<container_type> & operator++()
{
// Do nothing
return (*this);
}
push_insert_iterator<container_type> operator++(int)
{
// Do nothing
return (*this);
}
protected:
container_type & container; // reference to container
};
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
{
return push_insert_iterator<Container>(c);
}
这只是一个草稿,但你明白了。 使用push
方法(例如queue
, stack
)与任何容器(或容器适配器)一起使用。
std::queue
不是 STL 中的基本容器之一。 它是一个容器适配器,它使用基本 STL 容器之一(在这种情况下是std::vector
std::deque
或std::list
顺序容器之一)构建。 它专为 FIFO 行为而设计,不会在您希望insert_iterator
工作的给定迭代器上提供随机插入。 因此不可能像这样使用队列。
我能想到的最简单的方法是:
class PushFunctor
{
public:
PushFunctor(std::queue<int>& q) : myQ(q)
{
}
void operator()(int n)
{
myQ.push(n);
}
private:
std::queue<int>& myQ;
};
并像这样使用它:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
在这个简单的例子中,你可以写:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
这将制作vector
的副本并将其用作queue
的底层容器。
当然,如果您需要在队列构建后将内容入队,这种方法将不起作用。
对于 C++11
std::for_each( v.begin(), v.end(), [&q1](int data) { q1.push(data); } );
和 C++14
std::for_each( v.begin(), v.end(), [&q1](auto data) { q1.push(data); } );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.