我试图实现这样的目标:我有
struct {
int var1;
int var2;
int var3;
......
int var31;
}
现在我有一些整数' r'我在运行时读取,并且我想打印var ## r的值(即,如果r = 6,从结构打印var6),是否可以通过预处理器指令?我理解我可以通过跳转var1的地址sizeof(int)* r次来做到这一点,但我希望预处理器能够生成整个if-else链,我能以某种方式做到这一点吗?
更新:忘了提,不能修改给定的struct,因此不能使用数组
UPDATE2:我有这些限制(没有数组,nu跳转),因为最后我解析了clang生成的语法树,我希望在那里有纯粹的if / else语句
答案 0 :(得分:0)
如果您可以使用预处理器生成if
- else
链,如果您真的想要(您可能不这样做),但是如果它只是出现这种情况它最有可能不值得。我认为你应该重新考虑使用数组或偏移到结构中的可能性。
您可以在预处理器中以某种有限的程度构造循环。限制是您不能编写正确的循环,因此您将最终进入一个最终将进行有限迭代次数的构造。基本上你要循环n次的是将LOOP(n,...)
扩展为LOOP#n(...)
,然后定义LOOPn# for all possible values of
n`。
所以我们想要的是:
if( 0 ) ; // Note: empty statement
else if( r == 1 ) return o->var1;
else if( r == 2 ) return o->var2;
// etc
if(0)
是使每个变量在文本上处理相同。所以我们可以做第一步来定义:
#define HANDLE_VAR(n) else if( r == n ) return o->var ## n;
这意味着我们写了它
if(0) ;
HANDLE_VAR(1)
HANDLE_VAR(2)
// etc
然后我们定义循环结构:
#define LOOP(n,M) LOOP ## n(M)
#define LOOP(1) M(1)
#define LOOP(2) M(1) M(2)
// etc
然后我们的构造将是
if( 0 ) ; LOOP(31,HANDLE_VAR)
最后我们将它们全部包装成一个宏:
#define RETURN_VAR if(0) ; LOOP(31,HANDLE_VAR)
但是还有其他选择。最常见的解决方案是使用数组来存储变量。
另一种方法是编写自己的预处理器,支持正确的循环,有支持它的现成的模板处理器(例如genshi)。
第三个是计算结构中的偏移量。但是,建议的方法不符合标准。您需要做的是存储一组偏移量:
int StructName::* var_off[] = {
NULL,
&StructName::var1,
&StructName::var2,
// etc
};
然后使用o.*var_off[r]
访问var##r
(在检查r
是否在范围内之后)。