Время жизни объекта, захваченного ссылкой в ​​лямбде - PullRequest
1 голос
/ 01 марта 2020

У меня ниже код C ++. Лямбда захватывает объект карты по ссылке и может получить к нему доступ по истечении срока службы этого объекта карты.

using VOID_VOID = std::function<void ()>;
using VOID_MAP = std::function<void (std::map<std::string, std::string> &)>;
using FUNC_MAP = std::function<VOID_VOID (std::map<std::string, std::string> &)>;

FUNC_MAP getLambda(VOID_MAP func)
{
    auto outer_lambda = [func](std::map<std::string, std::string> & m)->VOID_VOID {
        auto inner_lambda = [func, m]() mutable {
            m.erase("A");
            m["D"] = "4";
            func(m);
        };
        return inner_lambda;
    };
    return outer_lambda;
}

VOID_VOID test(FUNC_MAP f)
{
  std::map<std::string, std::string> m = {{"A","1"}, {"C","3"}, {"B","2"}};
  return f(m);
}

int main()
{
  auto a = [](std::map<std::string, std::string> &z){
    for(auto p:z)
      std::cout << p.first << ":" << p.second << "\n";
  };
  auto outer_lambda = getLambda(a);
  auto fut = std::async (test, outer_lambda);
  auto inner_lambda = fut.get();

  auto fut2 = std::async (inner_lambda);
  fut2.wait();
  return 0;
}

Вывод вышеуказанного кода:

B:2
C:3
D:4

Поскольку жизнь карты объект m является test() функцией, как он все еще доступен из inner_lambda, где он захвачен ссылкой?

1 Ответ

1 голос
/ 01 марта 2020

Поскольку срок службы объекта карты m равен test()

Срок жизни m - это срок жизни лямбда-сигнала, который его определяет (= захватывает его по значению). Эта лямбда возвращается из getLamda() и передается в std::async() как inner_lambda в main(). Так что он жив и здоров в будущем. wait() в будущем выполняет inner_lambda, который стирает A, добавляет D и производит вывод, который вы видите.

...