Я создаю систему отправки событий, в которой функции регистрируются в обработчике, который затем вызывает их по своему усмотрению. Делегаты находятся в ассоциативном массиве динамических массивов, который отображает целочисленный «ключ» для ряда делегатов. Эта настройка необходима для того, чтобы обработчик был расширяемым с другими типами функций делегатов.
class Handler {
void addDelegate(void delegate(...) del, int event) nothrow @safe {
_tick[event] ~= del;
}
void callEvent(int event, ...) {
runDelegates(event, _argptr);
}
private:
void delegate(...)[][int] _delegates;
void runDelegates(uint type, ...) {
foreach (d; _tick[type]) {
d(_argptr);
}
}
}
Возникает проблема, когда я хочу передать аргумент этим делегатам. Не существует безопасного или проверяемого «типа», который позволяет передавать любую память. Использование varirgs без типа и передача _argptr
(значение, используемое для доступа к varargs) передает литеральное значение указателя в качестве аргумента.
Код, который я сейчас использую, вызывает такую ситуацию:
void vararg2(...) {
writefln("vararg2 _argptr: %s", _argptr);
}
void vararg1(...) {
writefln("vararg1 _argptr: %s", _argptr);
vararg2(_argptr);
}
int main() {
vararg1("a");
}
run.dlang.io
Если вы запустите пример, значения _argptr будут другими, и поэтому разыменование даст другой результат.
Единственный способ сделать это - заменить varargs аргументом void*
. Есть ли другой способ?