(最初询问提升用户ML: [heap] Singular handle issue with MSVC iterator debug facilities)
使用VS2017(版本15.2)和Boost 1.64,我正在编译一个使用boost::heap::d_ary_heap
的程序。
在调试配置中(默认为_ITERATOR_DEBUG_LEVEL
),当堆上项的句柄与默认构造的handle_type
实例进行比较时,我在运行时观察到问题。
顺便说一句,编译的handle_type
基于std::list::iterator
中定义的boost::heap::detail::priority_queue_mutable_wrapper
。
问题是MSVC迭代器调试工具用
中断执行File: c:\program files (x86)\microsoft visual
studio\2017\professional\vc\tools\msvc\14.10.25017\include\list
Line: 290
Expression: list iterators incompatible
AFAIU,handle_type{};
似乎产生包裹单数迭代器的句柄h
。
下面,我复制了最小的例子来重现问题。
#include <cstdint>
#include <functional>
#include <utility>
#include <boost/heap/d_ary_heap.hpp>
using NodeID = std::uint32_t;
using EdgeWeight = std::int32_t;
using HeapData = std::pair<EdgeWeight, NodeID>;
using HeapContainer = boost::heap::d_ary_heap<
HeapData,
boost::heap::arity<4>,
boost::heap::mutable_<true>,
boost::heap::compare<std::greater<HeapData>>>;
using HandleType = HeapContainer::handle_type;
int main()
{
HeapContainer heap;
auto const handle = heap.push(std::make_pair(100, 1));
handle == HandleType{}; // _DEBUG_ERROR("list iterators incompatible");
return 0;
}
在调试示例时,Visual C ++调试器不显示迭代器
由句柄包装为默认构造的 null节点指针。
相反,它显示垃圾:((???, ???), ???)
使用boost::heap::d_ary_heap
时这是否是已知的MSVC缺陷
或handle_type
以上实际上被误用了?
答案 0 :(得分:1)
我已经通过迭代器检查了MSVC库实现中的实现,并且必须得出结论:你不能通过default-construct获得一个经过检查的可比迭代器(拥有容器总是不匹配)。
有所不同:确实默认构造的句柄是单数的,但它们在MSVC上是如此单一,以至于它们只能被检查 - 与另一个单一实例进行比较。这很好:
HandleType{} == HandleType{}
获得可靠的&#34;不存在&#34; handle,我使用end-iterator句柄:
<强> Live On Coliru 强>
#include <cstdint>
#include <functional>
#include <boost/heap/d_ary_heap.hpp>
using NodeID = std::uint32_t;
using EdgeWeight = std::int32_t;
using HeapData = std::pair<EdgeWeight, NodeID>;
using HeapContainer = boost::heap::d_ary_heap<
HeapData,
boost::heap::arity<4>,
boost::heap::mutable_<true>,
boost::heap::compare<std::greater<HeapData>>>;
using HandleType = HeapContainer::handle_type;
int main() {
HeapContainer heap;
auto const none = heap.s_handle_from_iterator(heap.end());
auto const handle = heap.push(std::make_pair(100, 1));
assert(handle != none);
}
(当然静态可以作为HeapContainer::s_handle_from_iterator
)