reinterpret_cast on priority_queue 是否迭代了非标准的底层向量?

Is reinterpret_cast on priority_queue to iterate through the underlying vector non-standard?

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

它所做的基本上是创建一个 priority_queue 来使用向量处理整数。然后它 reinterpret_cast 将该队列放入向量指针中,以便可以迭代队列的元素(因为 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;
}

该标准不保证 布局 std::priority_queue class。如果这对您的实现有效,那一定是因为 std::vector 存储在 std::priority_queue object 的开头,但这当然不能依赖。

正确的做法是编写自己的 std::priority_queue 变体(<algorithm> header 已经包含必要的堆算法,例如 std::push_heap)或者从 std::priority_queue 派生一个 class,这使您可以访问引用底层容器的受保护成员 c

The following piece of code compiles and runs just fine

呸!那是幸运的。

but I have been reading up on reinterpret_cast and I can't really make out if it's standard compliant

是的

and is portable.

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

您可以可移植地重新解释将 A* 转换为 void*,然后再转换回 A*...仅此而已(好吧,还有一些用例,但它们是 具体,你需要在玩这根特殊的炸药棒之前了解它们。

In my head it should be since we explicitly specify the underlying container of the priority_queue but I haven't been able to get a straight answer so SO-wizards might have some insight into this piece.

std::priority_queue 是底层容器的特定适配。因为队列的正确操作取决于您不篡改底层容器,所以队列的接口故意向您隐藏它。

What it does is basically create a priority_queue that deals with integers using a vector. It then reinterpret_cast's that queue into a vector-pointer so that the elements of the queue can be iterated over (since priority_queue does not include that functionality itself).

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