我想简化事情,不单独创建enum列表,而是沿着函数调用创建枚举,该函数调用创建I与这些枚举所指向的数据。
我试着用#define来创建另一个#define,但是它不起作用:
int defcounter = 0;
#define make_def(enumname, somedata)
#define enumname defcounter
defcounter++;
func_call(somedata);
void createstuff(){
make_def(MY_ENUM_NAME, mydata);
make_def(MY_OTHER_ENUMNAME, mydata);
}
void dostuff(){
somefunc_call(MY_ENUM_NAME);
somefunc_call(MY_OTHER_ENUMNAME);
}
但是这会在#define enumname
:
error C2162: expected macro formal parameter
我怎样才能使它工作?
在c++中不可能在运行时创建新的类型(类、枚举、联合等等)。c++的一个主要特性是它是静态类型的——所有类型都必须在编译时知道。
预处理器命令(#define
, #if
, #pragma
, #include
,…)不能出现在宏/定义中。问题是,CPP (C- preprocessor)用换行符分隔命令,而C和c++不知道换行符。在C/c++中,你可以在一行上写所有的东西,对于预处理器命令,你不能。
#define MY_MACRO(name)
#define name##_macro something_cool
enum name{
....
}
// somewhere else
void myfunc(){
MY_MACRO(myfunc_enum);
}
现在,在预处理时,由于反斜杠:
#define MY_MACRO(name) #define name##_macro something_cool enum name{....}
现在,这个宏如何看待使用情况呢?
void myfunc(){
#define name##_macro something_cool enum name{....};
}
现在,预处理器必须再次运行#define
。但究竟什么属于#define
,什么不属于?对于编码员来说,当宏写在单独的行中时是很清楚的,但现在不再是这样了。
您想要的输出究竟是什么?你需要解释你认为你可能从C预处理器得到的输出。
您有作用域问题,并且试图在另一个宏的替换文本中定义宏。
范围宏make_def()
调用一个未定义的函数'func_call'。createstuff()
函数使用一个未定义的变量mydata
。函数dostuff()
似乎调用了一个未定义的函数somefunc_call()
,而这个未定义的函数可能已经在一个单独的函数中定义了。
如果枚举定义在一个函数内部,则该枚举不可用于该函数外部的代码,特别是不可用于被调用函数或调用函数。这本身就限制了你试图做的事情的效用。(是的,枚举值可以隐式地转换为int
或类似的类型,但它实际上不是正在使用的枚举类型。)
在宏中定义宏
你不能创建一个宏,它本身包含#define
或任何其他预处理器指令在其替换文本。
如果外部宏被调用,扩展不会将内部的#define
解释为预处理指令,因此它几乎总是以错误告终。在上下文中,#
必须是一个字符串化操作符,并且它后面的单词'define'必须是外部宏的参数名称,以便有机会工作。
// Does not work as intended
#define macro(define, prefix) #define another(name) foo(prefix ## name)
macro(something, other);
生成:
"something" another(name) foo(othername);
C99中的_Pragma
是'宏展开不能包含预处理器指令'的部分例外,但它(_Pragma
)不以#
开头。
您的宏是不正确的,因为您不能使用宏来创建另一个宏,不幸的是,因为令牌#在展开列表中具有特殊含义:它可以引用宏参数,或者展开另一个宏。一种简单(尽管设计得很差)的方法是使用旧的c风格的#define MY_ENUM_NAME value
,因为c宏不尊重作用域,但这不是一个好的设计。另一种可能是传入字符串参数并对其进行散列,但这取决于您想要做什么。