3

問題の例として、partialconcat次のコードでマクロを実装する方法はありますか?

#define apply(f, x) f(x)

apply(partialconcat(he),llo) //should produce hello

編集:

FOR_EACH可変個引数マクロが与えられた場合の別の例を次に示します(別の質問に対するこの回答の実装例を参照してください)。

より大きな目的のために、おそらく別のマクロ内で、いくつかのオブジェクトのメンバーを呼び出したいとしましょう。次のように動作するマクロcallMemberが必要です。

FOR_EACH(callMember(someMemberFunction), a, b, c);

を生成します

a.someMemberFunction(); b.someMemberFunction(); c.someMemberFunction();

これはcallMember(someMember)、次のように動作するマクロを生成する必要があります

#define callMember_someMember(o) o.someMember()
4

3 に答える 3

5

Vesa Karvonen の信じられないほどの「注文」言語/ライブラリを使用して、プリプロセッサで目的の結果を得ることができます: http://rosettacode.org/wiki/Order

これは、プリプロセッサ自体の上に第 2 の高級言語全体を実装することで機能し、カリー化やファースト クラス マクロなどをサポートします。CPP はそのように使用するように設計されておらず、ほとんどの C コンパイラはそれを処理できないため、重要な Order コードのコンパイルには非常に長い時間がかかります。また、非常に脆弱です。入力コードのエラーは、理解できない意味不明な出力を生成する傾向があります。

しかし、はい、1 つのプリプロセッサ パスで実行できます。予想していたよりもはるかに複雑です

于 2013-02-11T00:24:25.700 に答える
2

高次マクロを使用する:

#define OBJECT_LIST(V) \
    V(a) \
    V(b) \
    V(c)

#define MEMBER_CALL(X) \
    X.some_func();


OBJECT_LIST(MEMBER_CALL)

出力

$ g++ -E main.cc
# 1 "main.cc"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cc"
# 10 "main.cc"
a.some_func(); b.some_func(); c.some_func();

コンパイル時のループなのでカリー化は難しい。このOBJECT_LISTマクロは、このリストのすべてのユーザーがカリー化できる引数の数を定義します。(デフォルトの) 関数呼び出し引数は定義の一部です。デフォルトで提供されている引数を使用しないか、自分で定数値を使用するかを自由に選択できます。プリプロセッサの引数の量を減らす適切な方法を見つけることができませんでした。この事実は、この手法の一般性を制限します。

#define OBJECT_LIST(V) \
    V(a, 1,2,3) \
    V(b, 4,5,6)

#define MEMBER_CALL(X, A1, A2, A3) \
    X.somefunc(A1, A2, A3);

#define CURRY_CALL(X, A1, A2, A3) \
    X.somefunc(A1, 2, 2);

#define NO_CURRY_CALL(X, A1, A2, A3) \
    X.xomefunc(A1);


OBJECT_LIST(MEMBER_CALL)
OBJECT_LIST(CURRY_CALL)
OBJECT_LIST(NO_CURRY_CALL)

出力:

# 1 "main2.cc"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main2.cc"
# 12 "main2.cc"
a.somefunc(1, 2, 3); b.somefunc(4, 5, 6);
a.somefunc(1, 2, 2); b.somefunc(4, 2, 2);
a.somefunc(1); b.somefunc(4);
于 2014-07-17T08:17:25.780 に答える
1

C プリプロセッサは単純なテキスト プロセッサ「のみ」です。特に、あるマクロで別のマクロを定義することはできません。#defineマクロの展開からアウトを作成することはできません。

これは、質問の最後の 2 行が次のことを意味していると思います。

これはcallMember(someMember)、次のように動作するマクロを生成する必要があります

#define callMember_someMember(o) o.someMember()

これらは、C プリプロセッサを 1 回適用しただけでは達成できません (また、一般的に、マクロの定義方法に応じて、任意の回数プリプロセッサを適用する必要があります)。

于 2013-02-06T18:01:27.140 に答える