Почему захваченная переменная в C ++ 11 имеет другое значение внутри захвата? - PullRequest
1 голос
/ 27 апреля 2020

Я не уверен, как объяснить это поведение, приведенное здесь с минимальным примером. Почему size не правильно записано?

#include <iostream>
#include <vector>
using namespace std;


auto&& matcher1KO = [] (vector<int> &v){ 
    int size = v.size();
    cout << "size outside : " << size << "\n";  // print 1
    return [&] (bool b) {
      cout << "v.size() : " << v.size() << "\n"; // print 1
      cout << "size inside : " << size << "\n"; // print 0
    };
};

auto&& matcher2OK = [] (vector<int> &v){ 
    int size = v.size();
    cout << "size outside : " << size << "\n"; // print 1
    return [&] () {
      cout << "v.size() : " << v.size() << "\n"; // print 1
      cout << "size inside : " << size << "\n"; // print 1
    };
};

int main() {
  vector<int> v {+1};

  auto matcherf1 = matcher1KO(v); // 
  matcherf1(true);

  auto matcherf2 = matcher2OK(v);
  matcherf2();
}

1 Ответ

2 голосов
/ 27 апреля 2020

Оба кода имеют неопределенное поведение, все возможно.

Причина одинакова для двух случаев: переменная size является локальным объектом внутри operator() лямбды, она будет быть уничтоженным, когда вызов заканчивается. Вы захватываете size по ссылке, а ссылка привязана.

Изменение в режим захвата по значению было бы хорошо. например,

return [=] (bool b) {
  cout << "v.size() : " << v.size() << "\n"; // print 1
  cout << "size inside : " << size << "\n"; // print 1
};
...