使用std :: copy插入STL队列

时间:2009-11-12 16:28:41

标签: c++ stl copy queue insert-iterator

我想使用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_inserterstd::back_insert_iterator也会因同样的错误而失败。

我是否遗漏了一些明显的东西,或者insert_iterator只是不能使用队列?

8 个答案:

答案 0 :(得分:7)

队列不允许迭代其元素。

来自SGI STL Docs

  

队列是提供a的适配器   Container的受限子集   功能队列是“第一个   先出“(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是愚蠢的。

答案 1 :(得分:3)

std::queue不是STL意义上的容器,它是容器适配器,功能非常有限。对于您似乎需要的std::vectorstd::deque(“双端队列,这是一个”真正的容器“),似乎是正确的选择。

答案 2 :(得分:3)

我很确定它不起作用 - 队列提供push,但插入迭代器期望使用push_frontpush_back。没有真正的理由你不能写自己的push_insert_iterator(或者你喜欢的任何名字),但这有点痛苦......

答案 3 :(得分:3)

insert_iteratorback_insert_iterator仅适用于具有({1}}和insert方法的容器(或适配器) - push_back没有这些方法。您可以编写自己的迭代器,模仿这些,如下所示:

queue

除非这样的事情已经存在,但我很确定它没有。

答案 4 :(得分:2)

您需要的是push_inserter(即执行push进入队列的插入器)。据我所知,STL中没有这样的迭代器。我通常做的很遗憾地回到了古老的循环中。

如果你有勇气,你可以按照以下方式滚动自己的迭代器:

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方法(例如queuestack)与任何容器(或​​者,容器适配器)一起使用。

答案 5 :(得分:1)

std::queue不是STL中的基本容器之一。它是一个容器适配器,它使用一个基本的STL容器构建(在这种情况下,顺序容器之一是std::vector std::dequestd::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);

答案 6 :(得分:0)

在这个简单的例子中,你可以写:

vector<int> v;
v.push_back( 1 );
v.push_back( 2 );

queue<int, vector<int> > q(v);

这将复制vector并将其用作queue的基础容器。

当然,如果你需要在构造队列之后将事物排入队列,这种方法将不起作用。

答案 7 :(得分:0)

对于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); }  );