在priority_queue上进行interpret_cast,以遍历非标准的底层向量
Is reinterpret_cast on priority_queue to iterate through the underlying vector non-standard?
下面的代码编译和运行都很好,但我一直在阅读reinterpret_cast,我真的不知道它是否符合标准并且是可移植的。在我看来,这应该是因为我们明确指定了priority_queue的底层容器,但我还没有得到一个直接的答案,所以so向导可能会对这篇文章有一些了解。
它所做的基本上是创建一个优先级队列,该队列使用向量处理整数。然后,它将_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
类的布局。如果这对您的实现有效,那一定是因为std::vector
存储在std::priority_queue
对象的开头,但这肯定是不可靠的。
正确的做法是编写自己的std::priority_queue
变体(<algorithm>
标头已经包含必要的堆算法,如std::push_heap
),或者从std::priority_queue
派生一个类,这使您可以访问引用底层容器的受保护成员c
。
下面的代码编译并运行得很好
啊!那是幸运的。
但我一直在阅读relpret_cast,我真的不知道它是否符合标准
是的,是
并且是便携式的。
几乎从来没有。当然不是你使用它的方式。这是一种"如果你不知道它是如何工作的,就不要碰它"的东西。
你可以方便地重新解释将A*投射到空*,然后返回到A*。。。除此之外(好吧,还有一些用例,但它们是特定的,在你玩这根特定的炸药之前,你需要了解它们)。
在我看来,这应该是因为我们明确指定了priority_queue的底层容器,但我还没有得到一个直接的答案,所以so向导可能会对这篇文章有一些了解。
std::priority_queue是底层容器的一个特定的改编。因为队列的正确操作取决于您是否篡改底层容器,所以队列的接口会故意对您隐藏它。
它所做的基本上是创建一个优先级队列,该队列使用向量处理整数。然后,它将_cast的该队列重新解释为向量指针,以便可以迭代队列的元素(因为priority_queue本身不包括该功能)。
它真正做的是调用未定义的行为,这使得它不再可能对程序的任何部分的结果进行推理。如果它对你的环境有效,那就太可惜了。因为现在你会很想把它释放到我的记忆中,在那里它可能不会,或者可能会持续一段时间——同时默默地污染我的记忆,直到。。。轰!我的进程核心转储,我们都不知道为什么。
- 有什么方法可以遍历结构吗
- 在循环中按顺序遍历成员变量
- 遍历模板参数
- 在遍历处理程序的向量时注册和注销处理程序
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 遍历并行数组以确定C++中的最大数字
- 遍历顺序由 std::文件系统directory_iterator给出
- 循环遍历标准的正确方法::array<char*, N>
- 自定义链表const_iterator无法遍历列表的非const实例
- 在priority_queue上进行interpret_cast,以遍历非标准的底层向量
- 如何遍历非默认构造类的提升 MPL 列表
- 如何实现非递归 inOrder 遍历
- 当此列表包含父列表时,如何遍历列表,它使用标准列表
- 遍历标准:列表<wstring>
- 无法使用非递归顺序方法遍历二叉树
- 遍历矢量会导致错误,但循环的标准不会
- 在c++中遍历非连续枚举元素
- 输出或遍历集合的所有对组合的标准算法
- 定义遍历函数的const和非const版本
- 在C++中遍历非STL链表,可能吗