lambda capture by value vs reference

0

Witam
Mam problem z poniższym kodem. Dlaczego jak podam w capture list znak '=' to wtedy wątek od razu się zakańcza. A jak podam '&' to wtedy wątek się wykonuje do momentu wyjścia z maina. Powinno być na odwrót. Jak dasz & to znaczy że możesz sobie zmieniać wartość w ciele lambdy albo poza i zmiany są widoczne wszędzie. No bo referencja, samo przez się rozumie że tak powinno być. A ze znakiem '=' to myślałem, że zmiany w ciele lambdy nie są widoczne jeżeli od momentu wejścia do lambdy dokonałeś zmiany wartości. Również wice wersa, jak dokonałeś zmiany wartości w lambdzie to nie powinna ona być widoczna po wyjściu z lambdy. A to wszystko widze że na odwrót jest.

// Example program
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <atomic>

void funkcja()
{
    std::cout << "dupa zbita" << std::endl;
}

class Mon
{
  public:
      ~Mon() {stopMonitor(); std::cout << "dtor called" << std::endl;}
      void startMonitor();
      void stopMonitor();
  
  protected:
      std::atomic_bool isTimerRunning{false};
      std::thread monitoringThread;
};

void Mon::startMonitor()
{
    isTimerRunning = true;
    monitoringThread = std::thread([=]()
    {
       while(isTimerRunning)
       { 
           std::this_thread::sleep_for(std::chrono::milliseconds(200));
           if(isTimerRunning)
               funkcja();
       }
    });
}

void Mon::stopMonitor()
{
     isTimerRunning = false;
     monitoringThread.detach();
}

int main()
{
 {
  Mon mon;
  mon.startMonitor();
 }
  
  std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
2

Masz w tym kodzie UB - wątek przypisany do monitoringThread czyta zmienne obiektu mon po momencie, gdy kończy on swój żywot. Jakiekolwiek rozumowanie na temat przebiegu programu nie ma sensu, bo masz UB, i może ono być różne dla różnych opcji kompilacji, kompilatorów, systemów, faz księżyca i nastroju polityków.

Jeśli usuniesz {} wokół definicji mon, czyli gdy przedłużysz czas życia mon do otaczającej go funkcji main(), zachowanie będzie zgodne z przewidywaniami - [=] i [&] zachowają się identycznie, bo łapany jest wskaźnik this.

1 użytkowników online, w tym zalogowanych: 0, gości: 1