Timothy Hogan Ответов: 2

С++ универсальный цифровой подписи делегатов


В моей встроенной программе у меня есть 5 "софт-клавиш", расположенных с жидкокристаллическим экраном.

Я хотел бы иметь указатель для каждой кнопки, который может указывать на свободные функции или функции-члены и может принимать любую подпись. Этот указатель необходимо будет перенаправить на другие функции во время выполнения. Очевидно, что мне требуется какая-то функция делегата, однако все примеры делегатов, которые я видел, требуют знания сигнатуры функции во время компиляции. Возможен ли делегат универсальной подписи для c++11?

Я открыт для предложений относительно лучшего подхода.

Чтобы продемонстрировать свой идеал..

Delegate *bd1;
Delegate *bd2;
Delegate *bd3;
Delegate *bd4;
Delegate *bd5;

//initial assignment of buttons
bd1 = del_CallMainMenu();
bd2 = SelectedWidget->del_AdjustWidgetUp();
bd3 = SelectedWidget->del_AdjustWidgetDn();
bd4 = nullptr;
bd5 = del_Shutdown();


//Softkey 1 is pressed...
void del_CallMainMenu()
{
 //setup buttons for menu operations
bd1 = Menu->del_GoBack();
bd2 = Menu->del_SelectUp();
bd3 = Menu->del_SelDn();
bd4 = Menu->del_Move();
bd5 = Menu->del_Select(); //<--another example of where delegate may be used to call particular routines

//Do other stuff
}


Что я уже пробовал:

После нескольких недель чтения, я думаю, что знаю ответ, и я думаю, что мне это не понравится. Если это так, я бы не возражал против альтернативных предложений.

2 Ответов

Рейтинг:
4

CPallini

Насколько я знаю, не рассматривая "грязные хаки" (пытаясь победить сильно типизированную природу C++), вы не можете этого сделать.
Я бы использовал только одну сигнатуру функции, а затем адаптировал бы все свои функции, чтобы соответствовать ей. В рамках этого подхода вы, возможно, найдете полезным std::функция[^].


Timothy Hogan

Пытался также избежать ЗППП. Я также хотел бы сохранить его послушным. Я предположил, что подпись будет единственным вариантом. Я просто надеялся, что кто-то придумал какую-то потрясающую работу вокруг. Спасибо.

Рейтинг:
12

Richard MacCutchan

Нет простого способа обойти это, так как компилятор должен проверить, соответствует ли вызов сигнатуре функции. Вы можете определить каждую функцию, чтобы взять void* как его единственный параметр, а затем привести его внутренне к правильной структуре. Или вы можете использовать опцию varargs, где вы передаете один фиксированный параметр (например,количество других элементов) и любое следующее число. В таком случае объявление функции должно быть примерно таким:

int myfunc(int p1, ...)
{
}

// and your calls can be
int rc = myfunc(1, foo);
int rc = myfunc(3, foo, 10, "some text");

именно так это делают printf и его варианты.


Timothy Hogan

Этого я и боялся. Мне придется пойти с подписью varargs и, возможно, использовать какое-нибудь уродливое заявление Switch. Я действительно хотел избежать слепков, спасибо за ответ.