我试图参与一些C-preprocessor-only模板工作,以便键入一些代码。我试着把它简化一些,所以这个例子看起来很琐碎,毫无意义,但真正的挑战是如何获得“包含”阻塞。
假设我有一个“模板”文件,它在包含模板之前从定义T_ELEMENT_TYPE的其他源文件中获得#。
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef然后,我希望包含来自多个实例化站点的模板,但我只希望每个惟一的T_ELEMENT_TYPE生成一次模板函数(这样就不会创建重复的符号)。就像,说:
// Template-using file...
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE float
#include "Template.c"
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "Template.c"
#undef T_ELEMENT_TYPE
int someOtherFunc()
{
int foo = 42;
foo = SymbolForint(foo);
float bar = 42.0;
bar = SymbolForfloat(bar);
return foo;
}所以我在寻找一些我可以在模板代码中使用的东西。我想象它可能看起来像这样(虽然这不起作用):
// Template file...
#ifndef T_ELEMENT_TYPE
#error #define T_ELEMENT_TYPE
#endif
#define PASTER(x,y) x ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SYMBOLNAME EVALUATOR(SymbolFor, T_ELEMENT_TYPE)
#ifndef SYMBOLNAMEISDEFINED
#define SYMBOLNAMEISDEFINED EVALUTOR(DEFINEDFOR, T_ELEMENT_TYPE)
int SYMBOLNAME(T_ELEMENT_TYPE arg)
{
// do something with arg
return 0;
}
#endif // Guard #ifdef这个特定的咒语阻止模板的所有多个实例化,而不仅仅是针对不同的T_ELEMENT_TYPE值。
我能用什么伎俩来达到这个效果吗?或者说,我只是取消了C-Preprocessor的预订?
发布于 2010-09-03 14:09:14
我想你已经离开保留地了。宏名#define的第一个“参数”不受宏扩展的限制。因此,我认为预处理程序不能根据T_ELEMENT_TYPE的值定义不同的符号。预处理器也不能构造一个已经看到的类型的“列表”,并在其中检查是否存在。
所以我认为包括守卫必须在档案之外:
#ifndef included_mytemplatefile_h_int
#undef T_ELEMENT_TYPE
#define T_ELEMENT_TYPE int
#include "mytemplatefile.h"
#define included_mytemplatefile_h_int
#endif或者,如果您的模板文件头只声明函数SymbolFor_int,而不是定义它,那么多个包含是无害的。您可以在文件中不依赖于T_ELEMENT_TYPE当前值的部分周围设置一个普通的包含保护,包括PASTER、计算器、SYMBOLNAME的定义。您需要一个包含定义的单独模板文件,程序(而不是每个翻译单元)只需要拥有一次定义:
template_%.c :
echo "#define T_ELEMENT_TYPE $*" > $@
echo "#include \"mytemplatedefinitions.c\"" >> $@然后将template_int.o添加到链接到程序中的文件列表中。
https://stackoverflow.com/questions/3635921
复制相似问题