SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

ラムダ式でステップアップ! C++のプログラムから汎用的なアルゴリズムを切り出し利用してみよう


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

8. ラムダ式を使った汎用的なアルゴリズムの適用

 前節では、関数オブジェクトを作ることにより、Run関数内の環境を汎用アルゴリズムであるAppendIf関数とForEach関数に渡すことができました。

 しかし、関数オブジェクトを作るためには、一々クラスを用意する必要があります。面倒ですし、プログラムが複雑になります。

 ここまでしないと、汎用的なアルゴリズムを使えないのでしょうか?

ラムダ式

 そこでC++11から追加されたラムダ式です。簡潔な記述でクロージャーを実現することができます。

 C++のラムダ式については、次のページを参照してください。

書籍のリストの中から、タイトルか出版社名に "リ" を含むものをコンソールに表示(ラムダ式版)

 では、先のプログラムをラムダ式を使って書いてみましょう。関数オブジェクトと異なり、クラスを作る必要がない分ぐっとシンプルです。

Program.cpp
#include <iostream>
#include <list>
#include <vector>
#include <string>
using namespace std;

#include "Book.h"
#include "Publisher.h"
#include "MyCollection.h"
using namespace MyCollection;

class Program
{
public:
    void Run()
    {
        const vector<Publisher> publisherList = {
            Publisher(L"技術評論社"          ),
            Publisher(L"翔泳社"              ),
            Publisher(L"オライリー・ジャパン"),
            Publisher(L"SBクリエイティブ"    )
        };

        const list<Book> bookList = {
            Book(L"4774157155", L"C++ ポケットリファレンス"        , 0),
            Book(L"4798108936", L"C++ の絵本"                      , 1),
            Book(L"4798119768", L"独習 C++ 第4版"                  , 1),
            Book(L"4873110637", L"C++ プログラミング入門"          , 2),
            Book(L"4797376686", L"C++ テンプレートテクニック 第2版", 3)
        };

        const wstring searchWord = L"リ";
        list<Book>    filteredBookList;

        AppendIf(
            bookList,
            filteredBookList,
            // ラムダ式 (searchWord を値でキャプチャ、publisherList を参照でキャプチャ)
            // -> の前の const Book& book が入力で後が bool 型の出力
            [searchWord, &publisherList](const Book& book) -> bool {
                return book.GetTitle().find(searchWord) != wstring::npos ||
                       publisherList[book.GetPublisherIndex()].GetName()
                                      .find(searchWord) != wstring::npos;
            }
        );
        ForEach(
            filteredBookList,
            // ラムダ式 (publisherList を参照でキャプチャ)
            // -> の前の const Book& book が入力で後が実行内容
            [&publisherList](const Book& book) -> void {
                wcout << L"コード: "     << book.GetCode ()
                      << L", タイトル: " << book.GetTitle()
                      << L", 出版社: "
                      << publisherList[book.GetPublisherIndex()].GetName()
                      << endl;
            }
        );
    }
};

int main()
{
    wcout.imbue(locale("Japanese", locale::ctype));
    Program().Run();
    return 0;
}

 実行結果は、元々のプログラムと同じです。

実行結果
コード: 4774157155, タイトル: C++ ポケットリファレンス, 出版社: 技術評論社
コード: 4873110637, タイトル: C++ プログラミング入門, 出版社: オライリー・ジャパン
コード: 4797376686, タイトル: C++ テンプレートテクニック 第2版, 出版社: SBクリエイティブ

 ラムダ式を使うことで、余計な記述(本来のプログラムのロジックでない部分)が減り、簡潔な記述となりました。

9. まとめ

 C++における汎用的なアルゴリズムの分離について考察しました。

 汎用的なアルゴリズムがどのように分離されると良いか、そして分離されたアルゴリズムがどのように使われると良いか、を述べました。

 今回は汎用的なアルゴリズムを自作しましたが、このようなアルゴリズムはC++のライブラリの中に既にたくさん存在し、同様に使うことができます。

 例えば、次のページでは<algorithm>ヘッダーなどに含まれるアルゴリズムが紹介されています。

 ラムダ式を活用すれば、簡潔な記述で、これらの既存のアルゴリズムを使うことができます。

 C++で汎用的なアルゴリズムを利用したり書いたりするために、ここで述べたことが参考になれば幸いです。

修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

小島 富治雄(フジヲ)

Microsoft MVP for C# (2005.07~)。 - 注目の MVP - Blog: プログラミング C# - 翔ソフトウェア (Sho's) - Web Site: 翔ソフトウェア (Sho's) - Twitter: Fujiwo 著書: - Windows8〔業務アプリ〕開発読本 (共著)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8094 2014/10/14 16:20

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング