LoginSignup
9
3

More than 5 years have passed since last update.

ラムダ式を使えば、簡単にコールバック関数に引数を渡せる

Last updated at Posted at 2017-03-09

あらまし

コールバック関数に引数を渡すには少し手間が必要ですが、
ラムダ式を利用すれば簡単に書けるよって話です。

std::sortでの例

例えば、「ある数値に近い順でソートしたい」場合、
std::sortにて実現する際は、関数オブジェクトを用意する必要がありました。
※何故これをするかの理由は、省略します。理解しているという前提で話を進めますm( _ _ )m

5に近い順でソート(関数オブジェクト)
class AbsDist
{
public:
  AbsDist(int ref) :_ref(ref){};
  bool operator() (int l, int r) const {
    return abs(l - _ref) < abs(r - _ref);
  }
private:
  int _ref;
};

int main(int argc, _TCHAR* argv[])
{
  std::vector<int> numbers1 = { -1, 10, 2, 5, 6, -5, -10, 9, 8, 5 };
  int ref = 5;  
  std::sort(std::begin(numbers1), std::end(numbers1), AbsDist{ref});
  print(numbers1); // 5, 5, 6, 2, 8, 9, 10, -1, -5, -10
  return 0;
}

プログラムの中で、このような処理が何度も実行されるならまだしも、
たった数回の場合は、そのためにわざわざクラスを作るのが手間です。
そういうときは、ラムダ式で書くことが出来ます。

5に近い順でソート(ラムダ式)
int main(int argc, _TCHAR* argv[])
{
  std::vector<int> numbers2 = { -1, 10, 2, 5, 6, -5, -10, 9, 8, 5 };
  int ref = 5;  
  std::sort(std::begin(numbers2), std::end(numbers2),[&ref](int l, int r){
    return abs(l - ref) < abs(r - ref);
  });
  print(numbers2); // 5, 5, 6, 2, 8, 9, 10, -1, -5, -10
  return 0;
}

ちなみに、こういう書き方もできます。

5に近い順でソート(ラムダ式2)
int main(int argc, _TCHAR* argv[])
{
  std::vector<int> numbers3 = { -1, 10, 2, 5, 6, -5, -10, 9, 8, 5 };
  int ref = 5;  
  auto absDist = [&ref](int l, int r) -> bool{
    return abs(l - ref) < abs(r - ref);
  };
  std::sort(std::begin(numbers3), std::end(numbers3),absDist);
  print(numbers3); // 5, 5, 6, 2, 8, 9, 10, -1, -5, -10
  return 0;
}

ただこれは、ソート実行時に引数を指定できない&明確でないため、状態がいまいちわかりづらいかなと。

まとめ

ラムダ式を使えば、簡単にコールバック関数に引数を渡すことができました。
今回はstd::sortを例にしましたが、他の関数にももちろん応用できますので、是非お試しあれ。

ソース

9
3
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
9
3