Как запретить макрос с пустым аргументом?

Заметил, что могу передать пустой аргумент вместо нормального для параметра макроса. Можно ли запретить такое поведение, сделав в таком случае ошибку компиляции?

#define AtLeastOneArg(arg, ...) arg

int main() {
  AtLeastOneArg(;, ;); // compiles - OK
  AtLeastOneArg(;);    // compiles - OK
  AtLeastOneArg();     // compiles - unexpected
}

Ответы (1 шт):

Автор решения: HolyBlackCat
#define CAT(x, y) CAT_(x, y)
#define CAT_(x, y) x##y

#define NONEMPTY(...) CAT(DETAIL_NONEMPTY_,__VA_OPT__(0))(__VA_ARGS__)
#define DETAIL_NONEMPTY_() DETAIL_EXPECTED_NONEMPTY_ARG(x)
#define DETAIL_NONEMPTY_0(...) __VA_ARGS__
#define DETAIL_EXPECTED_NONEMPTY_ARG()

Теперь NONEMPTY() - ошибка, а NONEMPTY(42) раскрывается в 42.

#define AtLeastOneArg(arg, ...) NONEMPTY(arg)

Как обычно, если вы пользуетесь MSVC, не забудьте /std:c++latest /Zc:preprocessor чтобы включить поддержку __VA_OPT__ (или 20 вместо latest).

→ Ссылка