Mam następujący (uproszczony) kod w moim obecnym projekcie:C++ lambda'this' wskaźnik unieważnianie po operacji przesuwania
#include <iostream>
#include <string>
#include <functional>
#include <vector>
class Test{
public:
Test() = default;
Test(const Test& other) = delete;
Test& operator=(const Test& other) = delete;
Test(Test&& other) = default;
Test& operator=(Test&& other) = default;
void setFunction(){
lambda = [this](){
a = 2;
};
}
int callAndReturn(){
lambda();
return a;
}
private:
std::function<void()> lambda;
int a = 50;
};
int main()
{
Test t;
t.setFunction();
std::vector<Test> elements;
elements.push_back(std::move(t));
std::cout << elements[0].callAndReturn() << std::endl;
}
Kiedy uruchamiam go, wartość 50 jest drukowany zamiast oczekiwanej wartości 2. Przypuszczam, że tak się dzieje, ponieważ funkcja lambda przechwytuje bieżący wskaźnik this
. Po operacji przenoszenia wskaźnik this
zmienia się, a funkcja zapisuje na niewłaściwym a
.
Teraz moje pytanie brzmi: Czy istnieje sposób na zmianę przechwyconego odniesienia lambda do nowego Test
, aby wydrukowano wartość 2?
Nie możesz po prostu zrobić 't-> a = 2;' i zapomnieć o wskaźniku elementu? – Galik
@Galik - Nie wiem dlaczego, ale odniosłem wrażenie, że OP chciał, aby członek nie był na sztywno. Dodam, że oczywiście z uwagi na to, że lambda bez wychwytywania jest jeszcze prostsza, jak zauważyliście. – StoryTeller
Wydaje mi się, że podstawowym problemem jest przechwytywanie wskaźnika lambda "this", który nie jest aktualizowany przez * move *. Podając bieżący wskaźnik 'this' jako parametr, lambda zawsze działa na poprawnym obiekcie. – Galik