为什么std.RedBlackTree作为地图中断了?

时间:2012-04-14 22:00:58

标签: d

我最终决定使用std.RedBlackTree而不是内置的关联数组(或哈希),因为我需要一个有序的关联数组。期望的行为与C ++ / STL中的std::map非常相似。

void main() {

  alias Tuple!(float, float) Pair;
  alias RedBlackTree!Pair Map;
  Map m1;
  m1.insert(Pair(1.1, 2.2));
}

上面的代码,取决于你如何编译它(有或没有-release),会导致分段错误或抛出断言。

同样的事情:

void main() {

  struct Pair { float first, second; }
  alias RedBlackTree!(Pair, "a.first < b.first") Map;
  Map m1;
  m1.insert(Pair(1.1, 2.2));
}

闻起来像个臭虫,但是有解决方法吗?

2 个答案:

答案 0 :(得分:8)

RedBlackTree是一个类,因此必须初始化。 m1默认为null。你所看到的相当于Java中的NullPointerException。

试试这个:

import std.stdio, std.container;
void main() {
  struct Pair { float first, second; }
  alias RedBlackTree!(Pair, "a.first < b.second") Map;
  Map m1 = new Map;
  m1.insert(Pair(1.1, 2.2));
}

此外,作为此编程示例的旁注:您可能需要考虑使用RedBlackTree!(Pair, "a.first < b.first")。原因是它会有一些奇怪的(不完全未定义,但可能不是你想要的)行为。

例如,Pair(1, 2) < Pair(1, 3)是真的。奇怪的是,Pair(1, 3) < Pair(1, 2)也是如此。

答案 1 :(得分:3)

我想指出,当你得到段错误时,你通常应该寻找的前两件事是空指针/引用和无限递归。您可以使用调试器确定它们的确切位置。

RedBlackTree是一个类,因此任何RedBlackTree的变量都是引用类型。因此,您必须为其分配除null以外的值,或者它将为null,并且当您尝试使用它时,您将获得段错误。如果你有一个变量是指向某个东西的指针,并且你试图使用它而不给它指定一个非空值,那么就会发生同样的事情。

您的初始化行应该是

Map m1 = new Map;

或者,使用RedBlackTree,您可以

Map m1 = redBlackTree!"a.first < b.first"(Pair(1.1, 2.2));

redBlackTree是一个辅助函数,用于在一行中创建元素并将其插入RedBlackTree