Що робить ## (подвійний хеш) у директиві препроцесора?


91
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;

Наведений вище рядок взятий з Unreal 4, і я знаю, що міг би задати його на нереальних форумах, але я думаю, що це загальне запитання на C ++, яке вимагає тут.

Я розумію, що перший рядок визначає макрос, однак я погано розбираюся в попередніх процесорах в C ++, і тому я там загубився. Логіка говорить мені, що зворотна коса риса означає, що декларація продовжується до наступного рядка.

FThreadSafeStaticStat трохи схожий на шаблон, але там відбувається # і синтаксис, якого я ще не бачив у C ++

Хтось може сказати мені, що це означає? Я розумію, що у вас може не бути доступу до Unreal 4, але я просто не розумію синтаксис.


6
Ви можете прочитати про оператора ## на cppreference , серед іншого
Кубі

1
##є / може називатися оператором конкатенації.
dyp

1
О, це досить класно! Це пояснює досить багато, дякую. Але чому використовується ключове слово struct? Рядок більше схожий на визначення змінної
DavidColson,

1
structВводить складний специфікатор типу , наскільки я можу судити.
dyp

2
Офіційна назва - "оператор вставки токенів", оскільки він поєднує два маркери попередньої обробки для створення іншого. Зауважте, що він дійсний лише в тому випадку, якщо результатом є дійсний маркер попередньої обробки, наприклад, ви не + ## 3можете зробити +3. (Але можна обійтися, + 3звичайно, без оператора)
М. М.

Відповіді:


175

## є оператором препроцесора для конкатенації.

Тож якщо ви використовуєте

DEFINE_STAT(foo)

в будь-якому місці коду він замінюється на

struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;

перед компіляцією коду.

Ось ще один приклад з мого допису в блозі, щоб пояснити це далі.

#include <stdio.h>

#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
    printf("Stumped?\n");
}

Ця програма буде скомпільована та успішно виконана і дасть такий результат:

Stumped?

Коли препроцесор викликається за цим кодом,

  • begin замінюється на decode(a,n,i,m,a,t,e)
  • decode(a,n,i,m,a,t,e) замінюється на m ## a ## i ## n
  • m ## a ## i ## n замінюється на main

Таким чином, ефективно begin()замінюється на main().


8
Я не очікував стільки думати, щоб навчитися поведінці ##, але, мабуть, зараз я ніколи цього не забуду? Тож спасибі.
NicoBerrogorry

2
Мені знадобилася секунда, щоб прослідкувати, але це була фантастична відповідь на запитання. Дякую.
n00dle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.