是否对priority_queue进行reinterpret_cast迭代底层向量非标准?

时间:2016-03-29 22:41:30

标签: c++ vector priority-queue reinterpret-cast

以下代码编译并运行得很好,但我一直在阅读reinterpret_cast,如果它符合标准并且可移植,我就无法确定。在我看来应该是因为我们明确指定了priority_queue的底层容器,但我还没有得到一个直接的答案,所以SO-Wizards可能会对这篇文章有所了解。

它的作用基本上是创建一个使用向量处理整数的priority_queue。然后,它将队列重新解释为一个向量指针,以便可以迭代队列的元素(因为priority_queue本身不包含该功能)。

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


int main() {
    std::priority_queue< int, std::vector<int> > pq;

    pq.push(100);
    pq.push(32);
    pq.push(1);

    auto o = reinterpret_cast<std::vector<int> *>(&pq);
    for (std::vector<int>::iterator it = (*o).begin(); it != (*o).end(); it++) {
        std::cout << (*it) << std::endl;
    }

    return 0;
}

2 个答案:

答案 0 :(得分:2)

该标准不保证this.finish()类的布局。如果这适用于您的实现,那一定是因为std::priority_queue存储在std::vector对象的开头,但这肯定不能依赖。

正确的做法是编写自己的std::priority_queue变体(std::priority_queue标头已包含必要的堆算法,例如<algorithm>)或从{{派生一个类1}},它允许您访问受保护的成员std::push_heap,该成员引用底层容器。

答案 1 :(得分:0)

  

以下代码编译并运行得很好

唷!那很幸运。

  

但是我一直在阅读reinterpret_cast,如果它符合标准,我就无法理解

是的

  

并且便携。

几乎没有。当然不是你使用它的方式。它是其中之一,如果您不确切知道它是如何工作的,请不要触摸它。的东西。

你可以移植重新解释一个A *转换为void *,然后回到A * ...而不是那个(好的,还有一些用例,但它们是具体的,你需要先了解它们才能使用这种特殊的炸药棒。)

  

在我看来,应该是因为我们明确指定了priority_queue的底层容器,但我还没有得到一个直接的答案,所以SO-Wizards可能会对这篇文章有所了解。

std :: priority_queue是底层容器的特定修改。因为队列的正确操作取决于您没有篡改底层容器,所以队列的界面会故意将其隐藏起来。

  

它的作用基本上是创建一个使用向量处理整数的priority_queue。然后,它将队列重新解释为一个向量指针,以便可以迭代队列的元素(因为priority_queue本身不包含该功能)。

它真正做的是调用未定义的行为,这使得它不再可能推断出程序任何部分的结果。如果它适用于您的环境,那真是太可惜了。因为现在你很想把它释放到我的地方,它可能会赢得,或者可能会持续一段时间 - 同时默默地污染我的记忆直到......砰!我的流程核心转储,我们都无能为力。