Мы можем избавиться от std::function
, лямбды и вектора для этого вопроса.Поскольку лямбда-выражения являются просто синтаксическим сахаром для классов с оператором вызова функции, ваш тестовый сценарий фактически такой же, как этот:
struct Foo
{
std::string variableValue = "hello";
void bar(std::string arg)
{
std::cout <<"From capture list, before: "<< variableValue << std::endl;
std::cout <<"From arg, before: " << arg << std::endl;
delete this; // ugrh
std::cout << "From capture list, after: " << variableValue << std::endl;
std::cout << "From arg, after: " << arg << std::endl;
}
};
int main()
{
Foo* ptr = new Foo();
ptr->bar(variableValue);
}
Аргумент функции в порядке, потому что это копия, но после delete this
членFoo::variableValue
больше не существует, поэтому ваша программа имеет неопределенное поведение при попытке его использовать.
Общепринято, что продолжение запуска самой функции допустимо (поскольку определения функций не являютсяобъекты и не могут быть "удалены"; они являются просто фундаментальным свойством вашей программы), если вы оставляете членов инкапсулирующего класса достаточно хорошо в одиночку.
Однако я бы посоветовал избегать этого шаблона, если вы на самом деле ненужно это.Будет легко спутать людей с обязанностями владения вашего класса (даже если «ваш класс» автономно генерируется из лямбда-выражения!).
Является ли список захватааннулирование ожидаемого результата?
Да.
Безопасно ли использовать любую другую локальную переменную, не только в списке захвата, после вызова std :: function destructor?
Да.
Существует ли предлагаемый способ / шаблон для обеспечения того же поведения более безопасным способом (исключая огромные переключатели / если в состояниях класса)?
Невозможно сказать наверняка, не понимая, что вы пытаетесь сделать.Но вы можете попробовать поиграть с сохранением shared_ptr
s в вашем векторе ... Просто будьте осторожны, чтобы не захватить shared_ptr
в самой лямбде, иначе никогда не будет очищено !Вместо этого может быть полезен захват weak_ptr
;оно может быть «преобразовано» в shared_ptr
внутри лямбда-тела, которое защитит жизнь лямбды на протяжении всего тела.