Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

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

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

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

目次

1. はじめに

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

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

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

 次の記事の姉妹記事です。そちらではこの記事をC#用にしています。併せて読まれるとC++との違いが分かると思います。

対象読者

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

必要な環境

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

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クリエイティブ

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

修正履歴

  • 2014/10/14 16:20 姉妹記事「ラムダ式でステップアップ! C#のプログラムから汎用的なアルゴリズムを切り出すことで、LINQについての理解を深めよう」の紹介を第一節に挿入しました。

  • 2014/09/18 16:20 第8章のソースコード中の「// Sample.cpp」という不要な行を削除。

著者プロフィール

  • 小島 富治雄(フジヲ)

    Microsoft MVP for C# (2005.07~)。 - 注目の MVP - Blog: プログラミング C# - 翔ソフトウェア (Sho's) - Web Site: 翔ソフトウェア (Sho's) - Twitter: Fujiwo...

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