Я пытаюсь связать обработчик тайм-аута с моим кодом gtkmm, как показано в книге gtkmm. Тем не менее, моя функция on_timeout() не нуждается в каких-либо аргументах, и я пытаюсь правильно создать объект sigc::slot
для перехода к функции connect
, поскольку я сталкиваюсь со следующей ошибкой (среди прочего):
error: no matching function for call to ‘bind(sigc::bound_mem_functor0<bool, DerivedWindow>)
и несколько
candidate expects 2 arguments, 1 provided
ссылаясь на sigc::bind
. Как я называю обе функции:
_timeout_slot = sigc::bind(sigc::mem_fun(*this,&DerivedWindow::on_timeout));
_connection = Glib::signal_timeout().connect(_timeout_slot,timeout_value);
Я делаю это на классе DerivedWindow
полученном из Gtk::Window
. Что я делаю неправильно? Нужно ли использовать sigc::bind
и sigc::mem_func
если мне не нужны аргументы?
Вам не нужен sigc::bind
поскольку вы не привязываете никаких дополнительных аргументов к слоту (речь идет о разыменовании указателя функции-члена для this
уже позаботились sigc::mem_fun
). Итак, этого достаточно:
_timeout_slot = sigc::mem_fun(*this, &MyWindow::on_timeout)
_connection = Glib::signal_timeout().connect(_timeout_slot, timeout_value);
Быстрый совет: если вы можете использовать С++ 11, вы можете просто передать lambdas в качестве аргументов для подключения, что делает вещи более читабельными:
_connection = Glib::signal_timeout().connect([this]{ return on_timeout(); }, timeout_value);
Для этого вам может потребоваться добавить
namespace sigc{
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
}
Кроме того, если вы хотите подключиться к сигналам экземпляра класса (например, Gtk::Button* btn
), вы можете сделать вещи еще более компактными, определяя макрос
#define CONNECT(src, signal, ...) (src)->signal_##signal().connect(__VA_ARGS__)
который затем позволяет вам писать
CONNECT(btn, clicked, [this]{ btn_clicked_slot(); });