6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ラムダ式をコピーしたときの挙動

Posted at

はじめに

こんなミスするの僕だけだと思いますが忘れないように記事にしておきます

本文

こういうコードを書いたとすると、

# include <iostream>
# include <functional>

struct Hoge{
  int x;
  std::function<int()> f;

  Hoge(int x): x(x), f{[&](){ return this->x; }} {}
};

int main() {
  
  Hoge hoge(0);
  std::cout << hoge.f() << "\n";

  hoge.x = 1;
  std::cout << hoge.f() << "\n";
}

出力はこうなりますね

0
1

書き方がよろしくないとかは今は許してください



ではこうしてみると

# include <iostream>
# include <functional>

struct Hoge{
  int x;
  std::function<int()> f;

  Hoge(int x): x(x), f{[&](){ return this->x; }} {}
};

int main() {
  
  Hoge hoge(0);

  Hoge fuga = hoge;
  std::cout << fuga.f() << "\n";

  fuga.x = 1;
  std::cout << fuga.f() << "\n";
}

出力はこうなります

0
0

つまり、ラムダ式がキャプチャしている変数は hoge のほうの x のままということです

そのため、こうすれば

# include <iostream>
# include <functional>

struct Hoge{
  int x;
  std::function<int()> f;

  Hoge(int x): x(x), f{[&](){ return this->x; }} {}
};

int main() {
  
  Hoge hoge(0);

  Hoge fuga = hoge;
  std::cout << fuga.f() << "\n";

  fuga.x = 1;
  std::cout << fuga.f() << "\n";

  hoge.x = 2;
  std::cout << fuga.f() << "\n";
}

ちゃんと書き換わります

0
0
2

おわりに

こうなることに全く気付かなくて一時間無駄にしました

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?