Boost Lambdaのキャプチャとポインタ渡しについての雑感


Boost.Lambdaに、キャプチャという機能がある。

キャプチャをつかうことで、ラムダ式に引数を取ることができるようになる。
下記の13行目の[]の中に値を入れることができる。

英語では。。

The pair of square brackets ([]) is often called lambda introducers which need not empty.
[]は、lambda introducersというそうな。

 1#include <vector>
 2#include <string>
 3#include <algorithm>
 4#include <iostream>
 5
 6int main() {
 7  std::string concat;
 8  char startCharacter = 'M';
 9  std::vector<std::string> names{"Midori", "Gubugubo", "Madori"
10                 , "Muramura", "Gyogyogyo", "Gmge", "Moooooo"};
11
12  std::for_each(names.begin(), names.end(),
13               [&concat, startCharacter](const std::string& name) {
14                 if (name.size() > 0 && name[0] == startCharacter) {
15                   concat += name + ", ";
16                 }
17               });
18  std::cout << concat << '\n';
19}

上では、文字列のリスト
names{"Midori", "Gubugubo", "Madori", "Muramura", "Gyogyogyo", "Gmge", "Moooooo"}

について、"M"で始まるものを、文字列concatに追加していく。


$ ./a.out 
Midori, Madori, Muramura, Moooooo,

13行目の[&concat, startCharacter]の&concatでは、ポインタ経由の値渡しを使っている。

ポインタ経由の値渡しとは?
昔からある方法で、関数の戻り値以外の方法で値を返してもらう方法である。

C言語では、関数から値を返してもらう際には、戻り値を使うことができるが、その戻り値は1つだけである。
そのため、2つ以上の戻り値を取得する際に使わるクラシックなテクニックである。

 1#include <stdio.h>
 2
 3void func(int *a, double *b)
 4{
 5  *a = 10;
 6  *b = 3.14;
 7}
 8
 9int main(void)
10{
11  int a;
12  double b;
13
14  func(&a, &b);
15
16  printf("a->%d b->%f \n", a, b);
17
18  return 0;
19}

14行目で


    14  func(&a, &b);

と、&をつけて、(つまり、引数としてポインタを渡している)、呼び出され側(関数)でそのポインタの指すアドレスに値を格納するようにする。

実行結果


$ ./a.out 
a->10 b->3.140000 

話が少しそれたが、ラムダ式キャプチャの
[&concat, startCharacter]の&concatも、同じ感覚である。と見てよい。

c言語のポインタは↓の書籍がハイスタンダードである。
http://kmaebashi.com/seiha2/index.html

初版が出たのが2001/1/1で、今も読まれているので、またあと20年は読まれる可能性が高い。
(`ー´)b