マクロVSテンプレート

注意: この記事は1年以上前に掲載されたものです。情報が古い場合がありますのでお気を付け下さい。

CやC++でプログラミングを行うときに、往々にしてマクロを使う。例えば以下の様にある値の乗数をとる場合、変数の型が不定の場合に以下のようにマクロを使うことがある。

[code lang=”c”]#include <stdio.h>

#define MULTIPLY(a,b) (a)*(b)

int main() {
int val = MULTIPLY(10, 20);
printf("result: %dn", val);
return 0;
}[/code]

この場合、実際には以下のように展開される。

[code lang=”c”]#include <stdio.h>

int main() {
int val = 10 * 20;
printf("result: %sn", val);
return 0;
}[/code]

上記の場合、C言語で型が不定の場合、上記ようにマクロを使うしか方法が無く、型の安全性が保証されない。また、通常の関数とは違い、あくまで文字を置き換えているに過ぎないため、C++でネームスペースやクラス内に定義することが出来ない(無視されてしまう)ほか、型の正確性の面でも問題を起こすことがある。さらに、通常の関数とは書き方が異なるため、戸惑いが発生して可読性にも悪影響をおよぼすこともある。

その場合、C++では、テンプレートを使用して以下のように表現することもできる。

[code lang=”cpp”]#include <iostream>

template<typename T> T multiply(T a, T b) {
return a * b;
}

int main() {
int val = multiply<int>(10 * 20);
std::cout << "result: " << val << std::endl;
return 0;
}[/code]

この場合は、呼び出し側で型を指定しているため、マクロを使う方法と比較して型の安全性が保証されている。また、マクロとは違い、ネームスペースやクラス内に定義しても基本的には問題を起こすことはなく、記法も通常の関数と近いものとなっている。また、コンパイラの判断によってインライン展開されれば、マクロと同様、関数呼び出しによるオーバーヘッドも発生しない(インライン展開されずに通常の関数として展開された場合は呼び出しオーバーヘッドが発生する)。

C++でマクロを使うか、テンプレートを使うかは状況や環境によって変わる部分が大きいが、個人的には読みやすさや表記の一貫性を考慮して、なるべくマクロを使わないで、インライン関数やテンプレートなどの代替手段を使ったほうが良いと考えている。

タイトルとURLをコピーしました