我的问题很简单:可以获取指向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
。
答案 0 :(得分:10)
是否有可能获得指向a的底层存储的指针 std :: queue container adapter?
简短回答:不。
std::queue
需要SequenceContainer
类型,例如std::deque
或std::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::deque
或std::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;
}