为什么队列接受vector作为其底层容器?

时间:2014-07-06 13:02:08

标签: c++ c++11 stl c++14

考虑以下代码:

std::queue<int, std::vector<int>> Q;
Q.push(1);
Q.push(2);

Live Demo

除了使用具有连续内存的容器作为std::queue的底层容器之外,还会显着降低排队操作的性能。性能,上面的代码是完全可以接受和编译的。但是,如果我们调用std::queue::pop成员函数(例如,Q.pop();),程序将无法编译,并且编译器正确地抱怨std::vector没有成员函数{{1 }}

Live Demo

问题:

  1. 为什么pop_front可以作为std::vector的基础容器,因为它不符合std::queue的标准?
  2. 是否缺少元编程魔法来检查std::queue的基础容器是否满足队列定义中的必要条件(例如std::queue) ?
  3. concepts-lite的出现,可能是在C ++ 17中解决了这个问题吗?

2 个答案:

答案 0 :(得分:1)

  

为什么std :: vector可以作为std :: queue的底层容器,因为它不满足std :: queue的标准?

不是。

  

检查std :: queue的基础容器是否满足队列定义中的必要条件(例如std::queue<int, std::vector<int>> Q;),是不是缺少元编程魔法?

这句话没有意义,但如果你问是否有可能在实例化时诊断这个,答案是肯定的。不过,这在很大程度上是浪费时间。为了进行比较,请注意越界std::vector::operator[]如何您的责任,并且不会导致诊断。

  

概念-lite的出现(可能是在C ++ 17中)是否可以解决这个问题?

因为这是一个“问题”,是的。

答案 1 :(得分:0)

撇开理论:在实践中,基于向量的队列实现(使用push_back / erase)几乎总是优于基于列表的队列实现。

亲自尝试。

之所以如此,通常是由于连续内存访问的可预测性,因为它与当今的CPU高速缓存管理有关:顺序数组访问(对于高速缓存预加载)比列表节点更具可预测性。

即使Bjarne Stroustrup也建议尝试将基于矢量的解决方案用于列表,因为在当今的硬件上,它们往往做得更好。