CodeZine(コードジン)

特集ページ一覧

C++0xの新機能「ラムダ式」を次期Visual Studioでいち早く試す

Visual Studio 2010 β1で遊んでみた

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/09/10 14:00

 Visual Studio 2010のVisual C++には、C++0Xの新機能が積極的に取り入れられています。本稿では、Visual C++ ver. 10に追加されたC++0X新機能のひとつ「ラムダ式(lambda expression)」を紹介します。

目次

C++0Xの新機能が搭載されたVisual Studio 2010

 Microsoftの開発者向け技術情報サイト「MSDN」では、Visual Studio 2010 β1 がリリースされています。IDEがWPFで作られていたり、.NET Frameworkのバージョンが上がっていたりと、Visual Studio 2010では様々な変更/拡張が施されているようですが、C++屋の筆者としては、Visual C++が部分的にせよC++の新規格(通称C++0X)の新しい機能を積極的に取り入れていることが、とても嬉しく思います。

 Visual C++ ver. 10に追加されたC++0Xの新機能のひとつ、「ラムダ式(lambda expression)」を少しばかり触ってみましょう。

関数オブジェクトとは

 C++がtemplateをサポートし、それにあわせてSTLに代表されるテンプレート・ライブラリがリリースされたのが、1990年代半ば辺りだったでしょうか。STLはベクタ(可変長配列)や双方向リストなどのデータ構造だけでなく、列挙や検索、あるいはソートなどのアルゴリズムを提供してくれます。

 アルゴリズムを提供するライブラリは、拡張性の高さが求められます。例えば、検索であれば条件を満たすか否かを判定する関数、ソートであれば2つの要素の大小を判定する関数を、ユーザーが自由に設定できなくてはなりません。

 STLではユーザー定義関数をアルゴリズムに与える方法として「関数オブジェクト」を導入しました。関数オブジェクトとは、平たく言えば、文字通り関数として機能するオブジェクト。オブジェクトxに対し、operator()が適用できる、すなわちx()できるならxは関数オブジェクトです。

 例えば、int配列の中からnで割り切れる最初の要素を検索する場合について、考えてみましょう。STLのアルゴリズムは、ヘッダ<algorithm>に定義されているfind_ifを使いましょう。

nで割り切れる要素の検索
#include <algoritm>
#include <iostream>

class can_divide {
  int n_;
public:
  can_divide(int n) : n_(n) {}
  // nで割り切れるなら true を返す
  bool operator()(int x) const { return x % n_ == 0; }
};

int main() {
  int ar[] = { 9, 7, 5, 3, 1, -2, -4, -6, -8, 0 };
  int n = 4;
  int* found = std::find_if(ar, ar+10, can_divide(n));
  if ( found != ar+10 ) {
    std::cout << n << " で割り切れる数 "
                   << *found << " が見つかりました。" << std::endl;
  }
}

 上記コードでは、class can_divideが関数オブジェクトです。コンストラクタでnを指定しておけば、can_divideのインスタンスfは、f(x)が呼ばれるとxnで割り切れるかを判断します。find_ifは、与えられた範囲にある要素を1つずつ関数オブジェクトに適用し、trueとなる位置(イテレータ)を返します。

 サンプルをもう1つ。<algoritm>が提供する関数sortを用い、要素の絶対値で昇順にソートしてみましょう。

絶対値で昇順にソート
#include <algorithm>
#include <iostream>

class abs_less {
public:
  bool operator()(int x, int y) const {
    return ( x > 0 ? x : -x ) < ( y > 0 ? y : -y);
  }
};

int main() {
  int ar[] = { 9, 7, 5, 3, 1, -2, -4, -6, -8, 0 };
  std::sort(ar, ar+10, abs_less());
  for ( int i = 0; i < 10; ++i ) {
    std::cout << ar[i] << " ";
  }
}

 この例では、class abs_lessが関数オブジェクトです。abs_lessoperator()は引数を2つ(xy)を取り、|x| < |y|ならばtrueを返します。std::sortは、この比較関数オブジェクトの結果に基づいて大小関係を判定し、昇順にソートします。


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

著者プロフィール

  • επιστημη(エピステーメー)

    C++に首まで浸かったプログラマ。 Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"り わんくま同盟でたまにセッションスピーカやったり 中国茶淹れてにわか茶人を気取ってたり、 あと Facebook とか。 著書: - STL標準...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5