Mam funkcji w klasie, która definiuje lambda i przechowuje je w zmiennej lokalnej statycznej:Kiedy jest "to" zrobione w lambda?
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";
}
};
ja również wykonać następujący test:
int main()
{
A a;
B b;
a.call_print();
b.call_print();
}
To, czego się spodziewam wydrukować, to:
A::print()
B::print()
Ale to, co naprawdę jest:
A::print()
A::print()
(adres ten sam obiekt jest również drukowane z każdym)
Podejrzewam, to ze względu na wychwytywanie this
. Zakładałem, że przechwyci on wartość this
, gdy zostanie wywołana, ale wydaje się, że jest przechwytywana w momencie zdefiniowania lambda.
Czy ktoś mógłby wyjaśnić semantyki przechwytów lambda? Kiedy faktycznie dostają się do funkcji? Czy jest to takie samo dla wszystkich typów przechwytywania, czy też jest to specjalny przypadek? Usunięcie static
rozwiązuje problem, jednak w moim kodzie produkcyjnym faktycznie przechowuję lambdę w nieco cięższym obiekcie, który reprezentuje gniazdo, do którego wstawiam sygnał później.
Może warto dodać, że to rzeczywiście stanowi bardzo niebezpieczny styl programowania, ponieważ jeśli 'a' zostaje usunięty, przyszłe wywołania' call_print' wywołają niezdefiniowane zachowanie i bardzo prawdopodobne awarie. – Xirema
@Xirema To prawda, ale nie sądzę, że jest to zachowanie, które próbuje uzyskać. –
Rozumiem semantykę słowa "statyczny", próbuję zrozumieć, czy lambda "obiecuje" uchwycić "to" * później *, lub jeśli zostanie przechwycone * w prawo *. W swojej odpowiedzi zareagowałeś na to. Chciałem, aby kontener dla lambda był statyczny, ale nie przechwytuje. Miałem nadzieję, że zostały rozdzielone między definicją i inwokacją. –