.data()等效于std :: queue

时间:2014-07-05 19:02:59

标签: c++ c++11 containers c++-standard-library

我的问题很简单:可以获取指向std::queue容器适配器底层存储的指针吗?

我正在使用SFML进行渲染的一些模拟,我使用SFML渲染目标(draw())的sf::RenderTarget方法来绘制整个数据。该方法具有类似C的接口,期望指向数据的指针和std::size_t,其中包含要绘制的元素数。

由于出于某些目的将数据存储在队列中,如果有某种方法可以将指针指向存储库中的队列,而不是将数据复制到向量,我将很高兴。 我知道std::queue默认情况下会调整容器std::deque,但我不知道如何实现循环缓冲区以及它的数据是否连续(所以我可以直接提取指向数据的指针)。

编辑:性能

看看下面的答案,让我注意到我没有使用std::deque,因为它有类似队列的界面,但是因为我真的需要快速排队。我当然可以使用std::vector。如果性能不是重点,我会使用向量的push_back()erase( begin() )。但我需要的是快速排队以及将该队列的数据有效地移动到渲染目标的方法。当然,如果余额排队与努力绘制它进入绘图方面,我将使用std::vector

2 个答案:

答案 0 :(得分:10)

  

是否有可能获得指向a的底层存储的指针   std :: queue container adapter?

简短回答:不。

std::queue需要SequenceContainer类型,例如std::dequestd::list。这些都不能保证连续存储,因此没有指向底层存储的指针的概念。

如果他们使用连续的循环缓冲区,这将在容器上施加固定大小,或者在需要调整容器大小时产生大量成本(如std :: vector can)。

您可以改为使用boost::circular_buffer

答案 1 :(得分:1)

最直观的想法是使用std::vector作为std::queue的底层容器来确保连续的内存,然后通过获取std::queue::front的地址来访问连续的存储空间包裹的std::vector

但是,正确地指出@Blastfurnace std::vector没有pop_front成员函数,当您打算调用std::queue::pop时,程序会爆炸。< / p>

同样如前所述,std::queue通常需要使用std::dequestd::list等容器作为其基础容器。由于它们的结构特征,这些容器是最合适的,因为它们可以有效地弹出它们的前部元件。但是,由于其连续的记忆std::vector缺乏这种多功能性。

此外,如果使用具有连续内存的容器可以显着提高您的应用程序,那么使用std::vector会更好,更直接。

然而,为了记录,您还可以执行以下操作以避免缺少std::vector pop_front成员函数。您可以定义从class继承的std::vector并实施pop_front成员函数,如下例所示:

#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>

template<class T, class Alloc = std::allocator<T>>
class queuevec : public std::vector<T, Alloc> {
public:
  void pop_front() {
   if(!this->empty()) this->erase(this->begin());
  }
};

int main() { 
  std::queue<int, queuevec<int>> Q;

  for(int i(0); i < 10; ++i) Q.push(i);

  Q.pop();

  int *t = &(Q.front());
  std::for_each(t, t + Q.size(), [](int const i){ std::cout << i << " "; });
  std::cout << std::endl;
}

LIVE DEMO