无法定义关联数组类型:opEquals不存在

Col*_*Two 3 d

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

Error: AA key type MyString does not have 'bool opEquals(ref const MyString) const
Run Code Online (Sandbox Code Playgroud)

我在第一次使用type时发现了这个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() {

}
Run Code Online (Sandbox Code Playgroud)

这里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/
...
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 5

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

问题在于方法的@safe注释opEquals.在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'
Run Code Online (Sandbox Code Playgroud)

解决方法是删除@safe或替换它@trusted.

请注意,此问题不会在DMD的开发版本中显示,因此应在2.067.0中修复.