まさに、プログラミング言語にマクロは必要ありません。たとえば、Java はマクロがなくても問題なく動作します。通常、マクロはコードをより明確かつ短くすると同時に、より危険なものにします。
では、マクロを使用する最良の方法は何ですか? コードで話しましょう。
マクロを使用すると、次のような問題に対する美しいソリューションを作成できます。
period
メンバーがone
、five
、ten
、fifteen
および と呼ばれる列挙型を定義するとしますthirty
。次に、これを行う方法は次のとおりです。
まず、次のようなヘッダー ファイルを作成しますperiod_items.h
。
//period_items.h
//Here goes the items of the enum
//it is not a definition in itself!
E(one)
E(five)
E(ten)
E(fifteen)
E(thirty)
次に、次のような別のヘッダー ファイルを作成しますperiod.h
。
//period.h
#include <string>
//HERE goes the enum definition!
enum period
{
#define E(item) item,
#include "period_items.h" //it dumps the enum items in here!
#undef E
period_end
};
period to_period(std::string const & name)
{
#define E(item) if(name == #item) return item;
#include "period_items.h"
#undef E
return period_end;
}
これで、関数を単純に含めperiod.h
て使用できるようになりました。to_period
:-)
この関数を次のように追加することもできますperiod.h
。
std::string to_string(period value)
{
#define E(item) if(value == item) return #item;
#include "period_items.h"
#undef E
return "<error>";
}
今、あなたはこれを書くことができます:
#include "period.h"
period v = to_period("fifteen"); //string to period
std::string s = to_string(v); //period to string
このソリューションが美しい理由
列挙型にさらにいくつかのメンバーを追加したい場合は、次のように追加するだけですperiod_items.h
。
//period_items.h
//Here goes the items of the enum
//it is not a definition in itself!
E(one)
E(five)
E(ten)
E(fifteen)
E(thirty)
E(fifty) //added item!
E(hundred) //added item!
E(thousand) //added item!
これで完了です。to_string
何も変更しなくても問題なく動作しto_period
ます。
--
私はこの解決策を自分の解決策から別の問題に取り、ここに投稿しました:
私は最良の方法は使用することだと思いますinline
マクロのすべての利点とコンパイル時のすべてのチェックを利用できます
C++ でマクロが役立つ主な目的は、コンパイルを制御することです。何かのようなもの:
#ifdef DEBUG:
//print some debug information
#endif
また
#ifdef OS_WINDOWS
//windows specific code
#
私は他に何も機能しない場所でのみマクロを使用します。
1つの例は、たとえば、エラー値から文字列への簡単なマッピングです。
switch(code) {
case ERR_OK: return "ERR_OK";
case ERR_FOO: return "ERR_FOO";
:
私は次のような単純なマクロを使用します
#define CASE_STR(x) case x: return #x
だから私はこれを単純化することができます
switch(code) {
CASE_STR(ERR_OK);
CASE_STR(ERR_FOO);
:
ただし、これらのケースは通常、デバッグ用です。
また、ブーストプリプロセッサスイートを使用して一度展開するGLSL(OpenGL Shading Language)ループを作成しました。これは、次のように使用できます。
const char *shader = "#version 120\n"
"..."
GLSL_UNROLL_FOR("int i",0,10,\
"foo += i\n" \
)
"...";
次に例を示します(簡単に保守できます)。
enum id {
#define ITEM(id, s) id,
# include "foo.itm"
#undef ITEM
nbItem
};
static char const *const s[] = {
#define ITEM(id, s) s,
# include "foo.itm
#undef ITEM
}
私の非常に個人的な意見では、優れたマクロは非常にまれなものです。それらのほとんどは時限爆弾のようなものなので、私はそれらをできるだけ避けようとしています.
マクロが適切であるためには、次のことを行う必要があります。
#define MACRO } someCode {
、これは最悪です)。