gpt4 book ai didi

c++ - 在处理之前评估宏参数

转载 作者:行者123 更新时间:2023-11-30 04:43:41 26 4
gpt4 key购买 nike

我希望能够从宏中生成这些选项:

  1. if(void* temp = func(arg)){ foo(temp, variable);return; }
  2. if(void* temp = func2(arg)){ foo(temp, variable2); 返回; }
  3. if(void* temp = func3(arg)){ foo(temp, variable3);return; }

依此类推,但如您所见,1 是唯一的特例。

我想写一个宏,它接受一个数字作为参数并生成一行代码,可能数字远大于 3。不幸的是,这需要在特殊情况下构建,如果用户传递了 1 并执行一般如果他们通过任何其他数字。有办法做到这一点吗?

最佳答案

如果您真的想为此使用 CPP,那很容易。间接 GLUE 和间接 SECOND 宏是您可以使用的核心工具:

#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(_,X,...) X

间接 SECOND 允许您在预处理器中进行模式匹配。运作方式是您构建第一个 token ,这通常只是一次性的。但是由于扩展是间接的,如果您构建的第一个标记是宏,它将首先扩展(即,作为可变参数的参数替换的一部分)。如果该扩展包含一个逗号,它可以在间接选择第二个参数之前转移一个“新的”第二个参数。您可以使用它来构建您的特殊案例。

这是一个使用此构造的 cpp 模式匹配器,它返回它的参数,除非它是 1,在这种情况下它扩展为没有标记:

#define NOT_ONE(N) SECOND(GLUE(TEST_IF_1_IS_,N),N)
#define TEST_IF_1_IS_1 ,

使用它,您的宏可能是:

#define DISPATCH_CASE(N) \
if(void* temp = GLUE(func,NOT_ONE(N))){ \
foo(temp, GLUE(variable,NOT_ONE(N))); \
return;
}

Demo (coliru)

更新:Visual Studio 版本

But I'm on Visual Studio, and I can't make it work. I think the problem is the __VA_ARGS__ expansion works differently on Visual Studio

对于 VS,我发现了另一种特定类型的间接寻址(将宏与其参数分开,以便 arg 列表可以在之前的简单 (...) 上下文中求值它被应用)帮助它弄清楚逗号分隔参数。通常我会在多个宏中重复相同的模式以避免蓝色油漆。

在这里,转化为稍微丑陋的:

#define GLUE(A,B) GLUE_C(GLUE_I,(A,B))
#define GLUE_I(A,B) A##B
#define GLUE_C(A,B) A B
#define SECOND(...) SECOND_C(SECOND_I,(__VA_ARGS__,,))
#define SECOND_I(_,X,...) X
#define SECOND_C(A,B) A B

Demo (goldbolt)

关于c++ - 在处理之前评估宏参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58122619/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com