##(双散列)在预处理器指令中做什么
What does ## (double hash) do in a preprocessor directive?
#define DEFINE_STAT(Stat)
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
上面这句话取自虚幻4,我知道我可以在虚幻论坛上问一遍,但我认为这是一个普通的C++问题,值得在这里问。
我知道第一行定义了一个宏,但我不太熟悉C++中的预处理器恶作剧,所以我在那里很困惑。逻辑告诉我反斜线意味着声明继续到下一行。
FThreadSafeStaticStat看起来有点像一个模板,但里面有#,还有我以前在C++中从未见过的语法
有人能告诉我这是什么意思吗?我知道你可能无法访问虚幻4,但这只是我不理解的语法。
##
是用于级联的预处理器运算符。
所以如果你使用
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()
。
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=%dn", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%dn", 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;
}
相关文章:
- 如何在编译时定义C++预处理器指令的值?
- 如何在 c++ 预处理器指令中使用 "#" 作为字符
- 有C++标准库 ifdef 或 ifndef 预处理器指令吗?
- 不能在预处理器指令中使用 printf
- ARMC6忽略预处理器指令
- 每个 #include 指令的预处理器的时间成本是多少?
- 是否可以转换预处理器指令中的字符?
- 如何使用C++中的处理器指令来实现快速算术运算
- 用于在运行时选择变量的 C++ 预处理器指令
- 如何使用预处理器指令包含两次具有不同代码的文件?
- 将预处理器指令作为语句的一部分
- C++ 预处理器指令函数
- 如何在整个编辑中遵循预处理器指令
- 将多个Pragma指令放入一个预处理器定义中
- Bullet Physics源代码未在X86中构建 - Visual Studio 2017中错误的预处理器指令
- 预处理器指令:为什么使用#Define的标题文件标识符与标头文件名不同
- 使用正则表达式筛选预处理器指令
- 该预处理器指令在这里可以接受
- 将使用预处理器指令来定义美元符号表示的内容会导致任何冲突
- 对测试单元使用预处理器指令的相关性