2013年2月14日木曜日

Templateの基礎


Templateの基礎です。
なんだかんだで、勉強不足で知らないことが多かったのでまとめたいと思います。

まず、引数の型からテンプレートパラメータが自動決定される、よくあるテンプレート関数です。

上記の場合、func1(100)などとすれば型が自動確定しますが、func1<char>(100)などとして、明示的にテンプレートパラメータで指定することもできます。

次は明示的なテンプレートパラメータ指定が必須な場合です。

戻り値にテンプレート型が使用されており、引数による型の自動特定はできません。 上記を使用する場合、func2<char>(100)などのようにして明示的にテンプレートパラメータを示さないとエラーになります。
また、下記のようにテンプレートパラメータが2つ以上ある場合においては、明示と省略表現を混在できます。

例えば、func3<char>(100)とも、func3<char,int>(100)とも書けます。
さらに、次のような型を指定したテンプレート関数を作ることもできます。

使うときにはfunc4<2>(10)などとします。 当然ですが、テンプレート関数はコンパイル時に静的に生成されるため、func4<a>(10)のように、テンプレートパラメータに変数を指定することはできません。 動的なパラメータは大人しく引数で渡して下さい。

しかし、ここで挙げたサンプルだけ見ると、テンプレートの利点がよく飲み込めないですね。 #defineなどのプリプロセッサと本質何が違うのでしょうか?なんとなくかっこ良く見えるとか? 実際書いててよくわからなくなってきました。
例えば、テンプレートの場合は、型がより安全に扱えるという利点があると思います (プリプロセッサは単なる文字列の置換にすぎないので)。 しかし、Policy-based Designのような技巧的な手法を使わないとtemplateの本領は見えてこないのかもしれないです。

プログラム中にはなるべく即値(イミディエイト)を書くべからずとはよく言われますが、そういう意味では#defineもtemplateも発想の着眼点は同じなのかもしれません。


2013年2月11日月曜日

Policy-based Design


最近、Modern C++ Designという本を読んでます。

この本、C++関連本の中でも上級者向けに位置づけられており買ったはいいものの、なかなか読めずにいました。そこで何となく始めたこのブログに、その内容をまとめていこうかと思います。

この本は、柔軟で再利用性の高いソフトウェアデザインをするためのC++のテクニックを解説したものです。そのために、templateや多重継承といったC++の言語機能を積極活用します。

今の時点で1章までしか読み終わっていませんが、おそらく普通のC++入門本などで学んだだけではこの発想に到達することはまずできなかったと思います。そもそも、templateや多重継承を使っているC++プログラマーがどれだけいるんでしょうか?実際、自分もごく限られた場合にしか使っていなかったし、STLなどのライブラリーも使用したことがありませんでした。

C++の継承メカニズムに今ひとつ柔軟性の無さを感じている方がいたとしたら、この本が提供するテクニックは驚きに値するものとなるかもしれません。著者が提唱するPolicy-based designは、本文中で下記のように紹介されています。

"この技術を簡単に説明すると、特定の動作や構造上の側面を専門に受け持った小さなクラス群(policy)を数多く用意し、そういったポリシーを組み合わせることによって、複雑なクラスの組立を行う設計支援手法ということになる"

ここで、"小さなクラス郡(ポリシー)"を組み合わせて使う複雑なクラスをホストクラスと呼んでいます。ホストクラスは、複数のポリシークラスを多重継承してその機能を実現します。

ホストクラスの例を下記に示します。

ホストクラスManagerはCreationPolicyとCheckingPolicyという2つのポリシークラスを多重継承することで機能を取り入れます。ここで、Creationポリシーはポリシーを導入するホストクラスに何らかのメモリ作成機能を提供するポリシー、CheckingPolicyはポインタに対してのなんらかのチェック機能を提供するポリシーと仮定します。

ここで注目すべきは、2つのポリシークラスはテンプレートクラスであるということです。つまり、ホストクラスは、導入したスーパークラスの詳細な機能が未定のまま、その機能を実現することになります。しかし、スーパースラスはポリシーという"ゆるやかなルール"によって規定されているため、ホストクラスはポリシーのルールに則って実装すればよいのです(ポリシーへの違反は、クラスを実体化した際に言語のセマンティクス・チェックによって検知されます)。

Managerホストクラスを利用するユーザーは、テンプレートパラメータを使って、2つのポリシークラスを下記のように、選択して利用します。

ここで、OpNewCreatorはCreationPolicyのルールに則って作成された何らかのメモリ作成ポリシーの実装、NoCheckはCheckingPolicyに則って作成された何らかのポインタ・チェック用ポリシーの実装です。

このように、複数あるポリシーから必要なポリシーを選択し、利用時に必要な機能をユーザに選択させることで、ソフトウェアの柔軟性と再利用性を高めていくという考え方がPolicy-based designの基本になります。この例では、メモリを作成する方法、ポインタをチェックする方法を、テンプレートパラメータによって指定しています。しかも、選択された機能を持つクラスMyManagerはコンパイル時に静的に生成されています。


2013年2月10日日曜日

EclipseでのC/C++開発環境構築

EclipseによるC/C++開発環境構築です。

参考にしたサイト[1][2]

簡単にまとめると下記のようになります。
  1. Cygwinのインストール
    Select Packagesで選択する項目
    ・gcc-core
    ・gcc-g++
    ・gdb
    ・make
  2. Windows環境変数の設定
    ・PathにCygwinのbinディレクトリ(C:\cygwin\binなど)を追加
  3. Java SE Development Kitのインストール
  4. Eclipse IDE for Java Developersのダウンロード
  5. Eclipse上からCDTのインストール
    (1) Help > Install New Software
    (2) Work with: 「Juno」を選択(インストールしたEclipseの名称)
    (3) Programming Languages > C/C++ Development Toolsにチェック
    (4)「Next」を押してインストール完了
※) CDT: C/C++ Development Tool

上記、Cygwinでインストールするパッケージは最小限です。
同じインストーラーを起動すれば、好きなものを後からいくらでも追加できます。
gdbを入れておくと、プログラムのトレース実行が可能になります。

Eclipseは最初からEclipse IDE for C/C++ Developersを落としても良かったですが、結局初期構成が違うだけであり、Javaも使うかもしれないので後からプラグインを追加する方法を選択。


これでひとまずのC/C++環境が整います。