Что означает тильда (~) в макросах?

На этом сайте код показывает вызовы макросов с использованием тильды в круглых скобках:

HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
//                                          ^^^

Что означает / делать? Я подозреваю, что это пустой аргумент, но я не уверен. Может быть, это специфично для C (99), например, __ VA_ARGS __ специфично для C99 и существует в C ++?

37
задан a3f 18 April 2015 в 16:51
поделиться

1 ответ

На вводной странице Boost.Preprocessor приведен пример в A.4.1.1 Горизонтальное повторение

#define TINY_print(z, n, data) data

#define TINY_size(z, n, unused)                                 \
  template <BOOST_PP_ENUM_PARAMS(n, class T)>                   \
  struct tiny_size<                                             \
      BOOST_PP_ENUM_PARAMS(n,T)                                 \
      BOOST_PP_COMMA_IF(n)                                      \
      BOOST_PP_ENUM(                                            \
          BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none)      \
  >                                                             \
    : mpl::int_<n> {};

BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) // Oh! a tilde!

#undef TINY_size
#undef TINY_print

Ниже приводится объяснение:

Процесс генерации кода запускается вызовом BOOST_PP_REPEAT макроса высшего порядка , который многократно вызывает макрос, названный его вторым аргументом (TINY_size). Первый аргумент указывает количество повторных вызовов, а третий может быть любыми данными; он передается без изменений вызываемому макросу. В этом случае TINY_size не использует эти данные, поэтому выбор для передачи ~ был произвольным. [5]

(выделено мной)

И есть примечание:

[5] ~ не является полностью произвольным выбором. Оба @ и $ могли бы быть хорошим выбором, за исключением того, что они технически не являются частью базового набора символов, который должны поддерживать реализации C ++. Идентификатор, такой как игнорируемый, может подвергаться макроразложению, что приводит к неожиданным результатам.

Тильда, следовательно, просто заполнитель, потому что аргумент требуется, но не нужен. Поскольку любой пользовательский идентификатор wannabe может быть расширен, вам нужно использовать что-то еще.

Оказывается, что ~ в значительной степени не используется (двоичное отрицание не так часто называют) по сравнению с, например, + или -, поэтому существует небольшая вероятность путаницы. Как только вы остановитесь на этом, его использование последовательно придает ему новое значение для тильды; как использование operator<< и operator>> для потоковой передачи данных стало идиомой C ++.

31
ответ дан 27 November 2019 в 04:59
поделиться