#новичкам
Бывают ситуации, когда вы хотите зарегистрировать коллбэк, в котором будет выполняться метод текущего класса.
Например, вы пишите класс приложения. Правила хорошего тона говорят вам, что нужно добавить поддержку graceful shutdown. Для этого получаем объект обработчика сигнала и регистрируем коллбэк на SIGINT и SIGTERM:
struct Application {
Application() {
SignalHandler::GetSignalHandler().RegisterHandler({SIGINT, SIGTERM}, [](){
Shutdown();
});
}
void Shutdown() {...}
};Сработает ли такой код?
Он не соберется. Будет ошибка:
'this' was not captured for this lambda function. Методу Shutdown нужен объект, на котором его нужно вызвать.Для этого в С++11 вместе с лямбдами ввели захват this. Это значит, что в лямбду сохраняется указатель на текущий объект. А синтаксис лямбды позволяет в таком случае не использовать явно this в ее теле:
struct Application {
Application() {
SignalHandler::GetSignalHandler().RegisterHandler({SIGINT, SIGTERM}, [this](){
// this->Shutdown(); - don't need this syntax
Shutdown();
});
}
void Shutdown() {...}
};До С++20 кстати можно было захватывать this в лямбду с помощью дефолтного захвата по значению и по ссылке:
SignalHandler::GetSignalHandler().RegisterHandler({SIGINT, SIGTERM}, [= /*& also works*/](){ // works
Shutdown();
});Однако в С++20 запретили неявный захват this по значению(что очень хорошо). Теперь либо явных захват this, либо через default capture by reference.
Be explicit. Stay cool.
#cppcore #cpp11 #cpp20