5

可変引数マクロで可変引数の前にデフォルト引数を追加することは可能ですか? たとえば、次のようなマクロのバージョンがあります

#define MACRO(arg1, ...) func(arg1, ##__VA_ARGS__)

以前のバージョンに影響を与えないように、可変引数の前にマクロにさらに 2 つのデフォルト引数を追加したいと思います。お気に入り:

#define MACRO(arg1, arg2 = "", arg3 = "", ...) func(arg1, arg2, arg3, ##__VA_ARGS__)

どんな助けでも大歓迎です。

4

3 に答える 3

5

できること:

struct foo {
    int   aaa;
    char  bbb;
    char  *ccc;
};

#define BAR(...)   bar((struct foo){__VA_ARGS__})

void bar(struct foo baz)
    /* set defaults */
    if (!baz.aaa)
        baz.aaa = 10;
    if (!baz.bbb)
        baz.bbb = 'z';
    if (!baz.ccc)
        baz.ccc = "default";

    printf("%d, %c, %s\n", baz.aaa, baz.bbb, baz.ccc);
}

...
BAR();                     // prints "10, z, default"
BAR(5);                    // prints "5, z, default"
BAR(5,'b');                // prints "5, b, default"
BAR(5, 'b', "something");  // prints "5, b, something"

これの悪い点 - ゼロ パラメータはパラメータなしのように扱われます。たとえばBAR(0, 'c')、文字列が生成されます。10, c, default

于 2010-02-24T11:59:06.620 に答える
4

私はこれが可能だとは思わない。コンパイラ/プリプロセッサは、2 番目と 3 番目の引数が可変引数の一部であるか、デフォルト値をオーバーライドするかをどのように認識しますか? これが、デフォルト値を持つパラメーターが関数の最後の位置になければならない理由です。

arg2 を指定して arg3 のデフォルト値を使用できるようにするには、2 つまたは 3 つのマクロが必要になると思いますが、これではエラーが発生しやすくなります。

#define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__)
#define MACRO2(arg1, arg2, ...) func(arg1, arg2, "", ##__VA_ARGS__)
#define MACRO3(arg1, arg2, arg3, ...) func(arg1, arg2, arg3, ##__VA_ARGS__)
于 2010-02-24T11:56:58.743 に答える
0

あなたの質問への答えとしてではなく、単にあなたの問題を解決する方法として:

#define MACRO(arg1, ...)          \
    /* pre-treatment */           \
    func(arg1, ##__VA_ARGS__)     \
    /* post-treatment */          \

void func (type1 arg1, type2 arg2 = "", type3 arg3 = "", ...);
于 2011-10-19T10:23:59.693 に答える