У меня есть функция в классе, который определяет лямбда и сохраняет его в локальной статической переменной:Когда это «захвачено» в лямбда?
class A
{
public:
void call_print()
{
static auto const print_func = [this] {
print();
};
print_func();
};
virtual void print()
{
std::cout << "A::print()\n";
}
};
class B : public A
{
public:
virtual void print() override
{
std::cout << "B::print()\n";
}
};
Я также выполнить следующий тест:
int main()
{
A a;
B b;
a.call_print();
b.call_print();
}
Я ожидаю, что будет напечатан:
A::print()
B::print()
Но то, что я действительно получаю:
A::print()
A::print()
(Тот же адрес объекта также печатается с каждым)
Я подозреваю, что это связано с this
захвата. Я предположил, что он будет захватывать значение , когда оно вызывается, однако оно, кажется, захватывается в момент, когда определяется лямбда.
Может ли кто-нибудь объяснить семантику захвата лямбда? Когда они действительно получают функцию? Это то же самое для всех типов захвата, или this
частный случай? Удаление static
устраняет проблему, однако в моем производственном коде я фактически храню лямбду в немного более тяжелом объекте, который представляет собой слот, в который я вставляю сигнал позже.
Может быть, стоит добавить, что это на самом деле представляет собой очень опасный стиль программирования, так как если 'a' удаляется, будущие вызовы' call_print' будут вызывать неопределенное поведение и, скорее всего, сбой. – Xirema
@Xirema Это очень верно, но я не думаю, что это поведение, которое он пытается получить. –
Я понимаю семантику 'static', что я пытаюсь понять, если лямбда« обещает »захватить' this' * позже *, или если она будет захвачена * справа, то *. Однако вы ответили на это в своем ответе. Я хотел, чтобы контейнер для лямбда был статичным, но не захватом. Я надеялся, что они будут разделены между определением и вызовом. –