3

パラメータの数でマクロをオーバーロードしようとしています。
もちろん、実際にマクロをオーバーロードすることはできません。

可変長マクロを使用して適切なマクロを選択しようとしました(__VA_ARGS__存在しない場合は、その前の最後のコマを削除するはずであるという事実を使用して - GCC Reference):

#define TEST1() printf("TEST1");
#define TEST2() printf("TEST2");

#define CHOOSER(x, y,FUNC,...) FUNC()

#define MANIMACRO(...) CHOOSER(,__VA_ARGS__,TEST1,TEST2)

int main(void)
{
    MANIMACRO(1);
    MANIMACRO();
}

アイデアは、__VA_ARGS__存在する場合、4つの引数をCHOOSERに渡す必要があり、3番目の引数は未使用の引数で「消えた」はずであるというものでした。したがって、TEST1 が選択されます。

パラメータがない場合は__VA_ARGS__ヌルになり、カンマを削除する必要があるため、TEST2が選択されて使用されます。

__VA_ARGS__したがって、全体がすでに展開された後、おそらく前処理段階の最後にのみ削除されるため、それは機能しないと思います。

それで、どうすればそのようなことをすることができますか?(vs2010)

4

2 に答える 2

3

この答えに基づいて:

#define TEST1(expr)           printf("test1")
#define TEST2(expr, explain)  printf("test2")

#define N_ARGS_IMPL2(_1, _2, count, ...) \
   count
#define N_ARGS_IMPL(args) \
   N_ARGS_IMPL2 args
#define N_ARGS(...) N_ARGS_IMPL((__VA_ARGS__, 2, 1, 0))
 /* Pick the right helper macro to invoke. */
#define CHOOSER2(count) TEST##count
#define CHOOSER1(count) CHOOSER2(count)
#define CHOOSER(count)  CHOOSER1(count)
 /* The actual macro. */
#define TEST_GLUE(x, y) x y
#define TEST(...) \
   TEST_GLUE(CHOOSER(N_ARGS(__VA_ARGS__)), \
               (__VA_ARGS__))

int main() {
  TEST(one); // singleArgumentExpansion(one)
  TEST(two, "foopy"); // twoArgumentExpansion(two, "foopy")
  return 0;
}
于 2012-08-15T17:48:08.540 に答える
1

まず、リンクするページは、それが GCC 拡張機能であると説明しています。タグが示すように Visual Studio 2010 を使用している場合、それが機能しないことに驚きはありません。

次に、それを正しく使用していません:##コマと__VA_ARGS__. これを行って、両方の TESTx マクロが TEST1 を出力するタイプミスを修正すると、gcc 4.4 で期待される動作が得られます。

#include <stdio.h>

#define TEST1() printf("TEST1\n");
#define TEST2() printf("TEST2\n");

#define CHOOSER(x, y, FUNC,...) FUNC()

#define MANIMACRO(...) CHOOSER(,##__VA_ARGS__,TEST1,TEST2)

int main(void)
{
    MANIMACRO(1);
    MANIMACRO();
}
于 2012-08-15T18:01:40.713 に答える