我希望能够从宏生成这些选项:
if(void* temp = func(arg)){ foo(temp, variable);return; }
if(void* temp = func2(arg)){ foo(temp, variable2);return; }
if(void* temp = func3(arg)){ foo(temp, variable3);return; }
以此类推,但是如您所见, 1 是唯一的特殊情况。
我想编写一个以数字为参数并生成此代码行的宏,该代码可能具有远大于3的数字。不幸的是,这需要特殊情况下的构造,如果用户传递1并执行常规如果他们通过任何其他数字。有办法吗?
答案 0 :(得分: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
允许您在预处理器中模式匹配。起作用的方式是构建第一个令牌,通常这只是一个一次性的东西。但是由于扩展是间接的,因此如果您构建的第一个标记是宏,它将首先扩展(即,作为可变参数的参数替换的一部分)。如果该扩展包含逗号,则可以在间接选择第二个参数之前移入“新的”第二个参数。您可以使用它来构建特殊情况。
这是一个使用此结构的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;
}
更新:Visual Studio版本
但是我在Visual Studio上,我无法使其正常工作。我认为问题在于__VA_ARGS__扩展在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