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

CodeZine / 2014年9月25日 14時0分

 本稿では、C++のプログラムをリファクタリングして、汎用的なアルゴリズムを切り出し、利用する流れをステップバイステップで解説します。また、C++11で採用されたラムダ式がそれを利用するのに、いかに便利なのかを紹介します。

■1. はじめに

 プログラミング言語 C++では「ラムダ式」と呼ばれるものが使えるようになり(C++11で採用され、C++14で改良された)、標準ライブラリのアルゴリズムの利用がより簡潔な記述でできるようになりました。

 この記事では、基本に立ち返って、どのようにしてアルゴリズムを記述し、それを利用するかを考えたいと思います。

 汎用的なアルゴリズムをどのように記述すると良いのか、そしてそのアルゴリズムがどのように使われると良いのか、を述べます。その中で、何故ラムダ式が便利なのか、その理由が分かってもらえれば幸いです。

●対象読者

C++で開発を行っている方初級から中級にステップアップしたいC++プログラマーの方●必要な環境

 Visual Studio 2013(注1)など、C++11以上のC++(ラムダ式が使えるC++)がコンパイル・実行できる環境。



注1
 無償版のVisual Studio Express 2013 for Windows Desktop(with Update 3)もあります。



■2. 最初のプログラム

 まず、C++で書いたサンプルプログラムを一つ用意します。

 このサンプルプログラムは、出版社クラス Publisherと書籍クラス Bookを持ちます。メインの部分では、PublisherとBookのコレクションをそれぞれ持ち、その中からある条件に一致したものを表示します。

●出版社クラス Publisher

Publisher.h
#pragma once #include <string> class Publisher { std::wstring name; public: Publisher(std::wstring name) : name(name) {} std::wstring GetName() const { return name; } };
●書籍クラス Book

 出版社のインデックスを持っています。

Book.h
#pragma once #include <string> class Book { std::wstring code; std::wstring title; unsigned int publisherIndex; public: Book(std::wstring code, std::wstring title, int publisherIndex) : code(code), title(title), publisherIndex(publisherIndex) {} std::wstring GetCode() const { return code; } std::wstring GetTitle() const { return title; } int GetPublisherIndex() const { return publisherIndex; } };
 この2つのクラスのインスタンスのそれぞれのコレクションを作り、その中から「特定の文字列を名称に含むもの」を表示してみます。 例えば、書籍のタイトルまたは出版社の名前に "リ" を含むものをコンソールに表示してみましょう。

●メイン プログラム(書籍のタイトルまたは出版社の名前に "リ" を含むものをコンソールに表示)

Program.cpp
#include <iostream> #include <list> #include <vector> #include <string> using namespace std; #include "Book.h" #include "Publisher.h" 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"リ"; for (list<Book>::const_iterator iterator = bookList.begin(); iterator != bookList.end(); iterator++) { const wstring publisherName = publisherList[iterator->GetPublisherIndex()].GetName(); if (iterator->GetTitle().find(searchWord) != wstring::npos || publisherName.find(searchWord) != wstring::npos) wcout << L"コード: " << iterator->GetCode() << L", タイトル: " << iterator->GetTitle() << L", 出版社: " << publisherName << endl; } } }; int main() { wcout.imbue(locale("Japanese", locale::ctype)); Program().Run(); return 0; }
 実行してみると、次のようにタイトルまたは出版社の名前に "リ" を含む書籍が表示されます。

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


CodeZine

トピックスRSS

ランキング