Невозможно определить тип ассоциативного массива: opEquals не существует
Я не могу использовать непримитивные типы в качестве ключей для ассоциативных массивов; попытка сделать это приведет к следующей ошибке в строке, где я определяю 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 говорит, что он не реализован. Тот факт, что этот фрагмент взят прямо из документации, заставляет меня подозревать, что это ошибка компилятора, но, может быть, я что-то упустил?
Запуск DMD под Linux, но проблема также происходит под 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/
...
1 ответ
Это случай вводящего в заблуждение сообщения об ошибке, выдаваемого компилятором.
Проблема с @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'
Обходной путь должен удалить @safe
или замените его на @trusted
,
Обратите внимание, что эта проблема не проявляется в версии разработки DMD, поэтому она должна быть исправлена в 2.067.0.