Boost堆元素句柄比较和MSVC迭代器调试工具

时间:2017-08-10 08:33:03

标签: c++ visual-c++ boost iterator

(最初询问提升用户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以上实际上被误用了?

1 个答案:

答案 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

调用