-4
#define EVENT_TYPE(DO) DO(EVENT_UNKNOWN), DO(EVENT_SIP), DO(EVENT_MEDIA), \
                     DO(EVENT_APP), DO(EVENT_TIMER), DO(EVENT_BREAK),  \
                     DO(EVENT_STOP), DO(EVENT_MAX)

C++ での定義に関するこのコード サンプルを理解するにはどうすればよいですか?

4

2 に答える 2

2

マクロは単純な置換です。したがって、EVENT_TYPE の arg get に入力したものはすべて、右側のイベントのリストで "DO" が表示されている場所に置き換えられます。たとえば、次のEVENT_TYPE( GUI )ように置き換えられます。

GUI(EVENT_UNKNOWN), GUI(EVENT_SIP), GUI(EVENT_MEDIA), \
GUI(EVENT_APP), GUI(EVENT_TIMER), GUI(EVENT_BREAK),   \
GUI(EVENT_STOP), GUI(EVENT_MAX)

これは、他のマクロと一緒に使用することを意図している可能性があります。そのため、GUI(またはそこにあるものは何でも) それ自体が、たとえば名前空間を前に追加するようなことを行うマクロになります (したがって、最初の要素は MyNamespace::MyUI::EVENT_UNKNOWN になります) ) または識別子文字列を連結します (したがって、最初の要素は GUI_EVENT_UNKNOWN になります)。

更新:あなたのコメントから:

#define STRINGIFY(VAR) #VAR

var に入力したものから文字列を作成します。通常は変数名ですが、式の場合もあります。したがって、プリプロセッサは次のように変換します。

int i = 42;
std::cout << STRINGIFY(i)   << " = " << i << '\n' 
          << STRINGIFY(i+1) << " = " << i+1 << '\n';

の中へ

int i = 42;
std::cout << "i"   << " = " << i << '\n' 
          << "i+1" << " = " << i+1 << '\n';

印刷されます:

i = 42
i+1 = 43

シンボル連結を行うこともできます:

#define CONCAT(X) prefix_##X##_suffix

int CONCAT(myVar) = 42;

となります:

int prefix_myVar_suffix = 42;

文字列を連結することもできますが、それは読者の演習として残します。

于 2013-03-26T03:12:07.053 に答える
1

DO関数やファンクターなど、指定したものに置き換えるテキスト置換を行います。DO生成されたコードは、 for each , ... の代わりに渡した functor の関数を呼び出しEVENT_UNKNOWN、a、b、c を配置したかのようにそれらを返します。

これを使用して、一連のイベントの列挙を作成できます。例えば:

// create array of all of EVENT_UKNOWN... as integers
int array[] = { EVENT_TYPE((int)) };

// Create array of strings
class Foo {
public:
   std::string operator()(int val) { ... }
};

Foo f;
std::string strings[] = { EVENT_TYPE(f); }
于 2013-03-26T03:12:42.203 に答える