Создание замыкания для std :: function - PullRequest
0 голосов
/ 24 февраля 2020

Я не уверен, что использую точную терминологию, но я постараюсь быть как можно более понятным, чтобы избежать путаницы.

Предположим, у меня есть переменная std :: function

std::function<void(int)>  callback ;

В силу некоторых причин, выходящих за рамки моей компетенции, я не могу изменить прототип функции. Я получаю переменную std :: function в какой-то момент в моем коде, и мне нужно вызвать ее. Что-то вроде этого:

int a = 10 // just an example value
callback(a); 

Теперь у меня есть другая переменная. Давайте назовем его id.

int id = rand(); // Let us assume that rand here generates a random variable
int a = 10 // just an example value
callback(a);

Я хочу, чтобы id был доступен внутри обратного вызова, т.е. я ищу некоторую форму закрытия. Есть ли способ сделать это без создания id статического / глобального.

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Нет, вы не можете этого сделать.

callback не имеет состояния, если оно не предназначено для состояния (которого не было).

Это не должно иметь значения, хотя : если у вас нет контроля над callback, то он уже не хочет использовать вашу переменную id. И если вы do имеете контроль над ним, то вы можете просто заменить его лямбда-выражением, которое захватывает переменную и делает с ней все, что вы хотите.

0 голосов
/ 24 февраля 2020

Вы можете изменить std::function:

std::function<void(int)> callback;
int id = rand();
callback = [=](int a){callback(a*id);};

Я использую лямбду здесь, чтобы создать новую безымянную функцию. Для этого требуется копия [=] из id и callback (той, что вы получили), а затем я назначаю лямбду обратно оригиналу callback.

Обратите внимание, что это также копирует id. Пример настолько ограничен, что я не могу быть уверен, что время жизни id достаточно велико. Вы можете захватывать по ссылке, но, как и со всеми ссылками в C ++, вы должны быть осторожны с временем жизни ссылочного объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...