Как можно связать функцию-член с переменным числом с функтором?
Я пытаюсь связать первый параметр функции variadic с помощью std:: bind, а затем передать возвращенный функтор в функцию connect() сигнала boost:: signal2::signal. Процесс работает нормально до тех пор, пока переменная функция не является функцией-членом. Вот что я хотел бы сделать:
class test {
public:
test() {}
void call_var_callback(string const& func, ...) {
va_list args;
va_start(args, func);
std::cout << "Calling variadic function: " << func << std::endl;
}
};
test t;
void register_callback2(std::map<string, boost::any>& sig_table,
string func, string event) {
auto event_entry = sig_table.find(event);
if (event_entry != sig_table.end()) {
if (event == "event1") {
auto sig = boost::any_cast<signal<void (void)>*>(sig_table["event1"]);
sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func)));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
} else {
std::cout << "No such event exists!" << std::endl;
}
}
int main( void ) {
// define events
signal<void (void)> event1;
signal<void (char const*)> event2;
signal<void (int, char const*)> event3;
// intialize event / signal lookup table
std::map<string, boost::any> sig_tbl;
sig_tbl["event1"] = &event1;
sig_tbl["event2"] = &event2;
sig_tbl["event3"] = &event3;
// connect the signals
register_callback2(sig_tbl, "func1", "event1");
register_callback2(sig_tbl, "func2", "event2");
register_callback2(sig_tbl, "func3", "event3");
// call the signals
for (int i = 1000; i > 0; --i) {
(*boost::any_cast<signal<void (void)>*>(sig_tbl["event1"]))();
(*boost::any_cast<signal<void (char const*)>*>(sig_tbl["event2"]))("0xBAAD");
(*boost::any_cast<signal<void (int, char const*)>*>(sig_tbl["event3"]))(5, "0xBEEF");
}
}
Когда я компилирую, я получаю сообщение об ошибке, в котором говорится, что "нет совпадения для вызова..." Где... это заполненный шаблонный тип вызова для привязки. Если я переместу определение call_var_callback() за пределы объекта 'test', все будет работать. Однако в моей реальной базе кода связанная функция должна быть членом класса, потому что она несет с собой состояние.
Заранее благодарю за внимание и помощь.
1 ответ
Когда вы связываете функции-члены, вы не берете адрес объекта. В вашем коде:
sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func)));
&t
это неправильно, это должно быть просто t
bind
поддерживает 2 основных способа привязки объекта:
- передать сам объект или
- указатель на объект (а также общий указатель вместо необработанного указателя)