D:来自std.container.BinaryHeap的奇怪行为以及用于比较的自定义函数

Koz*_*oss 3 struct pointers d binary-heap

我已经为一堆Node*s 编写了以下代码,这些代码可以在模块中找到node:

import std.exception, std.container;

public import node;

alias NodeArray = Array!(const (Node)*);
alias NodeHeap = BinaryHeap!(NodeArray, cmp_node_ptr);

auto make_heap() {
  return new NodeHeap(NodeArray(cast(const(Node)*)[]));
}

void insert(NodeHeap* heap, in Node* u) {
  enforce(heap && u);
  heap.insert(u);
}

pure bool cmp_node_ptr(in Node* a, in Node* b) {
  enforce(a && b);
  return (a.val > b.val);
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试在其上运行以下单元测试,其中make_leaf返回Node*初始化的给定参数:

unittest {
  auto u = make_leaf(10);
  auto heap = make_heap();
  insert(heap, u); //bad things happen here
  assert(heap.front == u);
  auto v = make_leaf(20);
  insert(heap, v);
  assert(heap.front == u); //assures heap property
}
Run Code Online (Sandbox Code Playgroud)

测试进入我评论标记的行,然后在行enforce(a && b)中抛出强制执行错误cmp_node_ptr.我完全迷失了为什么会这样.

use*_*816 5

你在这个运算符中做错了什么:

NodeArray(cast(const(Node)*)[])
Run Code Online (Sandbox Code Playgroud)

你显然想要创建空的NodeArray,但你真正得到的是具有一个空项的NodeArray.NodeArray构造函数将新数组的值列表作为参数,并传递一个"空数组"(基本上为null),从而创建带有一个null元素的NodeArray.

正确的方法是:

NodeArray()
Run Code Online (Sandbox Code Playgroud)

即:

auto make_heap() {
  return new NodeHeap();
}
Run Code Online (Sandbox Code Playgroud)

做出这个改变,一切都会好起来的.

ps似乎U类型的多个参数的D符号(U []值...)让你认为构造函数接受另一个数组作为初始化.

抱歉,修复了make_heap()代码:意外忘记在其中写入"NodeArray()".并再次编辑它,因为那里不需要空的NodeArray()调用.双重错误!