今日は、まともにラムダ関数を使った例でも書いてみることにします。コードはとっさに思い浮かんだウィンドウの列挙です。VC++10 CTP用です。

#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
#include <functional>
 
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
 
namespace egtra
{
    typedef std::tr1::function<bool (HWND)> enum_func_t;
 
    BOOL CALLBACK xEnumWindowsProc(HWND hwnd, LPARAM lp)
    {
        return (*reinterpret_cast<enum_func_t*>(lp))(hwnd);
    }
 
    inline BOOL EnumWindows(enum_func_t fn)
    {
        return ::EnumWindows(xEnumWindowsProc,
            reinterpret_cast<LPARAM>(&fn));
    }
 
    std::basic_string<TCHAR> GetWindowText(HWND hwnd)
    {
        std::basic_string<TCHAR> s;
        if (int tmpLen = GetWindowTextLength(hwnd))
        {
            ++tmpLen;
            s.resize(static_cast<size_t>(tmpLen));
            int len = GetWindowText(hwnd, &s[0], tmpLen);
            s.resize(len);
        }
        return s;
    }
}
 
int main()
{
    std::deque<HWND> hwnds;
    egtra::EnumWindows([&hwnds](HWND hwnd) -> bool {
        hwnds.push_back(hwnd);
    	return true;
    });
    std::for_each(hwnds.begin(), hwnds.end(), [](HWND hwnd) {
        std::cout << std::hex << hwnd << '\t'
            << egtra::GetWindowText(hwnd) << std::endl;
    });
}

日本語で書くとこんな感じです: EnumWindowsでウィンドウハンドルを取得し、hwndsへ蓄え、そしてハンドルとタイトルを出力するためfor_eachで中身を巡回しています。

中心となる部分がmain関数に全て収まりました。このコードでは名前空間egtraに放り込んだ部分に相当するライブラリが充実したら相当おもしろそうですが、どうせこれまでどおりそこも自分で書き続ける羽目になるのでしょう。

egtra::xEnumWindowsProcは独立した関数にせず、egtra::EnumWindows内にラムダ関数で定義しようとしましたが、キャプチャなし(外側の環境の影響を一切受けないもの)でも関数へのポインタに変換するのは駄目でしたね。そのようなこれもできたらできたで良かったのにとは思います。

2011年6月2日追記:その後、キャプチャなしのラムダは関数へのポインタへ変換できることとなりました。現在(この追記を書いている時点)のGCC(4.5以降)は対応しています。ということで、修正したコードを新しい記事にして載せました: Lambda その2・改


スポンサード リンク

この記事のカテゴリ