У меня возникают проблемы с созданием переменной типа "указатель на функцию-член" (PTMF) "на лету" (то есть путем закрепления некоторых аргументов существующей функции-члена через std::bind). Мой вопрос в том, возможно ли это когда-либо со стандартом С++ 11 или пост-С++ 11.
Преамбула: у меня есть класс, в котором хранится статический массив констант std::functions, инициализированных из PTMF, далее именуемых «обработчиками». Изначально это были обычные функции-члены с именем и реализацией, поэтому я никогда не использовал C++11 и std::function. Затем я решил, что многие из них очень похожи, и решил сгенерировать их с помощью «функции-генератора». Я хотел бы избежать использования шаблонов для генерации, потому что количество этих почти одинаковых обработчиков в будущем резко возрастет (около 200+), а шаблонизация просто приведет к раздуванию кода.
Если бы рассматриваемые PTMF были статическими, у меня не было бы проблем с генерацией обработчиков через std::bind. Упрощенный пример:
#include <iostream>
#include <functional>
using namespace std;
struct A {
typedef function<void(int)> HandlerFn;
static void parametrized_handler(int i, const char *param) {
cout << "parametrized handler: " << param << endl;
}
static void handler(int i) { cout << "handler 1" << endl; }
int mm;
};
static const A::HandlerFn handler2 = [](int) { cout << "handler 2" << endl; };
static const A::HandlerFn handler3 = bind(A::parametrized_handler,
placeholders::_1,
"test_param");
int main()
{
A::handler(42);
handler2(42);
handler3(42);
return 0;
}
Выход:
$ ./a.out
handler 1
handler 2
parametrized handler: test_param
Проблема возникает, когда я обращаюсь к нестатическим функциям-членам. std::bind не может генерировать объект функции, который действует как PTMF. Я знаю, что могу передать реальный объект в качестве первого аргумента для привязки и получить работающую функцию, но это не то, чего я хочу: когда я инициализирую статический массив const, объектов вообще нет, и результат привязки будет в любом случае действовать как обычная функция, не являющаяся членом.
Ожидаемая реализация для нестатических функций-членов (с воображаемым связующим std::bind_mem):
#include <iostream>
#include <functional>
using namespace std;
struct A;
struct A {
typedef function<void(int)> HandlerFn;
void parametrized_handler(int i, const char *param) {
mm;
cout << "parametrized handler: " << param << endl;
}
void handler(int i) const { mm; cout << "handler 1" << endl; }
const HandlerFn handler2 = [this](int i) { mm; cout << "handler 2" << endl; };
int mm;
};
// An imaginary PTMF binder
// static const A::HandlerFn handler3 = bind_mem(A::parametrized_handler,
// placeholders::_1,
// "test_param");
int main()
{
A a;
(a.handler)(42);
(a.handler2)(42);
//(a.handler3)(42);
return 0;
}
Выход:
$ ./a.out
handler 1
handler 2
Итак, есть ли способ реализовать привязку аргумента PTMF?
.
или.*
нельзя.->
было бы громоздко, но как насчет->*
? Вы можете обернуть свои функции в собственный класс и для этого перегрузитьoperator ->*
. - person Quentin   schedule 27.12.2017