D Can';t定义关联数组类型:opEquals不';不存在

D Can';t定义关联数组类型:opEquals不';不存在,d,D,我不能使用非基本类型作为关联数组的键;尝试这样做将在我定义AA的行上导致以下错误: Error: AA key type MyString does not have 'bool opEquals(ref const MyString) const 我第一次发现这一点是在使用类型CollisionHandler[Tuple!(TypeInfo,TypeInfo)]时,其中CollisionHandler是函数指针类型的别名 但是,即使是“使用结构或联合作为键类型”标题下的示例代码也会失败,并出

我不能使用非基本类型作为关联数组的键;尝试这样做将在我定义AA的行上导致以下错误:

Error: AA key type MyString does not have 'bool opEquals(ref const MyString) const
我第一次发现这一点是在使用类型
CollisionHandler[Tuple!(TypeInfo,TypeInfo)]
时,其中
CollisionHandler
是函数指针类型的别名

但是,即使是“使用结构或联合作为键类型”标题下的示例代码也会失败,并出现相同的错误:

import std.string;

struct MyString
{
    string str;

    size_t toHash() const @safe pure nothrow
    {
        size_t hash;
        foreach (char c; str)
        hash = (hash * 9) + c;
        return hash;
    }
    // opEquals defined here?
    bool opEquals(ref const MyString s) const @safe pure nothrow
    {
        return std.string.cmp(this.str, s.str) == 0;
    }
}

int[MyString] foo; // errors here

void main() {

}
在这里,
MyString.opEquals
被定义并应该有正确的签名,但是dmd编译器说它没有实现。事实上,这段代码直接来自文档,这让我怀疑这是一个编译器错误,但也许我只是遗漏了什么

在Linux下运行DMD,但在Windows 7下也会出现此问题。DMD版本:

$ dmd --help
DMD64 D Compiler v2.066.1
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
...

这是编译器发出的误导性错误消息的情况

问题在于
opEquals
方法上的
@safe
注释。在2.066.1中,
std.string.cmp
不是
@safe
-但是,编译器显示错误的错误消息。如果将
opEquals
重命名为其他名称,例如
foo
,则会收到不同的错误消息:

test.d(19): Error: safe function 'test.MyString.foo' cannot call system function
'std.algorithm.cmp!("a < b", string, string).cmp'
test.d(19):错误:安全函数“test.MyString.foo”无法调用系统函数
'std.algorithm.cmp!(“a
解决方法是删除
@safe
,或将其替换为
@trusted

注意,这个问题在DMD的开发版本中没有表现出来,所以应该在2.067.0中修复