2017-08-10 55 views
1

(最初要求在提升用户ML: [heap] Singular handle issue with MSVC iterator debug facilities升压堆元素手柄比较和MSVC迭代器调试设备

使用VS2017(15.2版)和Boost 1.64,我编译它使用boost::heap::d_ary_heap程序。

在调试配置中(默认为_ITERATOR_DEBUG_LEVEL),我在运行时观察堆上项目的句柄与默认构建的handle_type实例。

顺便说一句,编入的handle_type基于std::list::iteratorboost::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++调试不显示由所述手柄缠绕作为迭代 默认构造与空节点指针。 相反,它显示垃圾:((???, ???), ???)

这是一个已知的MSVC的缺点与boost::heap::d_ary_heaphandle_type以上工作实际上是误用而?

回答

1

我已经阅读了我通过迭代器检查MSVC库实现中的实现的方法,并且必须得出结论,默认情况下您无法获得检查可比的迭代器 - 构建(拥有容器总是不匹配)。

不同的是:默认构造的句柄实际上是单数的,但它们在MSVC上非常单一,所以它们只能被检查 - 与另一个单一实例进行比较。这是罚款:

HandleType{} == HandleType{} 

为了得到一个可靠的 “不存在的” 手柄,我会使用最终迭代器手柄:

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

+0

非常感谢你的答案。我很高兴奇点已被证实(是的,我也意识到与另一个奇异实例比较是犹太教)。非常感谢可靠的​​不存在的句柄建议(你已经阅读了我在两行之间的实际问题:-))。真棒! – mloskot