【c++】ラムダ式にキャプチャする値の参照とコピーについて復習

はじめに

こんにちは、野村です。

前回PHP7の無名関数を復習している最中「c++ではどうやるんだっけ?」てなことが頭をよぎったのですよ。
しばらくc++を書いてなかったのですっかり忘れてしまってた。

なので今回はc++のラムダ式について復習してみます。

無名関数を即時実行

#include <iostream>
using namespace std;

int main(){
  []{cout<<"test"<<endl;}();
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
test

引数を設定して実行

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

int main(){
  [](string const & str){cout<<str<<endl;}("test");
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
test

参照とコピー

とにかく「&」は参照なのだな。おぼえておこう。

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

int main(){
  string a = "test";
  [&]{cout<<a<<endl;}(); //参照
  [=]{cout<<a<<endl;}(); //コピー
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
test
test

参照してみる

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

int main(){
  string a = "test1";
  [&]{a="test2";}(); //参照
  cout<<a<<endl;
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
test2

コピーした変数には代入できない

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

int main(){
  string a = "test1";
  [=]{a="test2";}(); //コピー
  cout<<a<<endl;
  return 0;
}

これはコンパイルエラーになる。

mutableを使えば代入できる

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

int main(){
  string a = "test1";
  [=]()mutable{a="test2";}(); //コピー
  cout<<a<<endl;
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
test1

キャプチャを指定する。

変数単位でコピーと参照を設定できる。

[a, &b]()mutable{}(); //aはコピー、bは参照
[=, &a]()mutable{}(); //aは参照、それ以外はコピー
[&, a]()mutable{}(); //aはコピー、それ以外は参照

thisを使った場合は強制的に参照になる

thisはポインタだから。ちょっと考えればわかる。

#include <iostream>
using namespace std;

struct S {
  int i;
  void f(){
    [=]{this->i=1;}();
  }
};

int main(){
  S s;
  s.f();
  cout<<s.i<<endl;
  return 0;
}

実行結果

$ g++ main.cpp -std=c++14&&./a.out
1

最後に

以上、c++のラムダ式について復習してみました。

というわけで、今回はこれにて。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

野村 野村のプロフィール
メインPCはWindows10のVirtualBox上のFreeBSD。Linux/Unixの小ネタを求めて日々右往左往してたりする。twitterやってます⇒https://twitter.com/usr_sbin。Facebookもやってます⇒https://www.facebook.com/nomura.634