#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
上面的代码取自 Unreal 4,我知道我可以在虚幻论坛上提问,但我认为这是一个一般性的 C++ 问题,值得在这里提问。
我知道第一行定义了一个宏,但是我并不精通 C++ 中的预处理器恶作剧,所以我迷路了。逻辑告诉我反斜杠意味着声明继续到下一行。
FThreadSafeStaticStat 看起来有点像模板,但里面有 #'s 和我以前在 C++ 中从未见过的语法
有人能告诉我这是什么意思吗?我知道您可能无法访问 Unreal 4,但这只是我不理解的语法。
##
是/可以称为连接运算符。
struct
引入了一个详细的类型说明符。
+ ## 3
来制作 +3
。 (但您当然可以执行 + 3
,无需操作员)
##
是用于连接的预处理器运算符。
所以如果你使用
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()
。
TLDR; ##
用于连接,#
用于字符串化(来自 cppreference)。
##
连接连续的标识符,当您想将函数作为参数传递时它很有用。这是一个示例,其中 foo
接受函数参数作为其第一个参数,运算符 a
和 b
作为第二个和第三个参数:
#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;
}