##(double hash)在预处理器指令中做了什么?

时间:2014-04-09 22:21:01

标签: c++ c concatenation c-preprocessor

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

以上这一行是从虚幻4中获取的,我知道我可以在虚幻的论坛上提出这个问题,但我认为这是一个普遍的C ++问题,值得在这里提出。

我理解第一行定义了一个宏,但是我不熟悉C ++中的预处理器恶作剧,所以我在那里迷失了。逻辑告诉我反斜杠意味着声明继续到下一行。

FThreadSafeStaticStat看起来有点像模板,但是那里正在进行#C ++中我从未见过的语法

有人能告诉我这意味着什么吗?我知道您可能无法访问虚幻4,但它只是我不理解的语法。

2 个答案:

答案 0 :(得分:139)

##是连接的预处理程序运算符。

所以如果你使用

DEFINE_STAT(foo)

代码中的任何地方,都会被

取代

struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;

在编译代码之前

以下是我a blog post的另一个例子,可以进一步解释这一点。

#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()

答案 1 :(得分:2)

TLDR; ## 用于串联,# 用于字符串化(来自 cppreference)。

## 连接连续的标识符,当您想将函数作为参数传递时它很有用。下面是一个示例,其中 foo 接受一个函数参数作为它的第一个参数,而运算符 ab 作为第二个和第三个参数:

#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)

int main(int argc, char **argv) {
    int a = 2;
    int b = 3;
    printf("%d+%d=%d\n", a, b,  foo(my_sum, a, b));  // 2+3=5
    printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
    return 0;
}

# 连接参数并将输出括在引号中。例子是:

#include <stdio.h> 
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
    bar(1, "x", int); // 1, "x", int
    return 0;
}