##(双哈希)在预处理程序指令中做什么?


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

上面的内容摘自Unreal 4,我知道我可以在虚幻的论坛上提出这个问题,但是我认为这是一个一般的C ++问题,值得在这里提出。

我知道第一行定义了一个宏,但是我并不精通C ++中的预处理器恶作剧,所以我迷路了。逻辑告诉我反斜杠表示声明继续到下一行。

FThreadSafeStaticStat看起来有点像模板,但是里面有#的代码,而且是我在C ++中从未见过的语法

有人可以告诉我这是什么意思吗?我了解您可能无法使用Unreal 4,但这只是我不了解的语法。


6
你可以阅读##操作上cppreference,除其他事项外
Cubbi

1
##是/可以被称为串联运算符。
dyp 2014年

1
哦,太酷了!它解释了很多,谢谢。但是为什么要使用struct关键字呢?该行看起来更像是一个变量定义
DavidColson 2014年

1
据我所知,这里struct介绍了一个详尽的类型说明符
dyp 2014年

2
正式名称是“令牌粘贴运算符”,因为它结合了两个预处理令牌以产生另一个令牌。请注意,仅当结果是有效的预处理令牌时才有效,例如,您不能+ ## 3进行make +3。(但是您+ 3当然可以在没有操作员的情况下进行操作)
MM

Answers:


174

## 是串联的预处理器运算符。

所以如果你用

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.