C++:如何在函数中创建枚举?
我想简化事情,不单独创建枚举列表,而是沿着函数调用创建枚举,该函数调用在我用这些枚举指向的位置创建数据。
我尝试创建 #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
我怎样才能使其工作?
I want to simplify things, by not creating a list of enum separately, but create the enums along the function call which creates the data where i point with those enums.
I tried to make #define which would create another #define, but it didnt work:
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);
}
But this will create error at the #define enumname
:
error C2162: expected macro formal parameter
How can I make this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C++ 中,不可能在运行时创建新类型(类、枚举、联合等)。 C++ 的主要特性之一是它是静态类型的——所有类型都必须在编译时已知。
It is impossible to create new types (classes, enums, unions, whatever) at runtime in C++. One of the major features of C++ is that it is statically typed - all types must be known at compile time.
预处理器命令(
#define
、#if
、#pragma
、#include
等)不能出现在宏/定义。问题是,CPP(C 预处理器)通过换行符分隔命令,而 C 和 C++ 不知道换行符。在 C/C++ 中,您可以将所有内容写在一行上,但对于预处理器命令,则不能。现在,在预处理时,由于
\
反斜杠,这些行都被粘成一大行:现在,该宏如何看待用法?
现在,预处理器必须再次运行该
#define
。但到底什么属于#define
,什么不属于呢?对于编码员来说,宏何时被写在单独的行中是很清楚的,但现在不再是这样了。Preprocessor commands (
#define
,#if
,#pragma
,#include
, ...) cannot appear in macros / defines. The problem is, that the CPP (C-Preprocessor) seperates commands by newlines, while C and C++ are unaware of newlines. In C/C++ you can write everything on one line, for preprocessor commands, you can't.Now, at preprocessing time, those lines all get glued into one big line, thanks to the
\
backslash:Now, how would that macro look at usage?
Now, the preprocessor has to run over that
#define
again. But exactly what belongs to the#define
, and what doesn't? For the coder it was clear when the macro was written in seperate lines, but now it isn't anymore.您想要的输出到底是什么?您需要解释您认为可能从 C 预处理器输出的内容。
您遇到范围问题并尝试在另一个宏的替换文本中定义宏。
范围
宏
make_def()
调用未定义的函数“func_call”。createstuff()
函数使用未定义的变量mydata
。并且函数dostuff()
似乎使用一个可能已在单独函数内定义的枚举来调用未定义的函数somefunc_call()
。如果在一个函数内部定义了枚举,则该枚举不可用于该函数外部的代码,特别是不可用于被调用函数或调用函数。仅此一点就限制了您似乎尝试做的事情的效用。 (是的,枚举值可能会隐式转换为
int
或某种类似的类型,但它实际上并不是正在使用的枚举类型。)在宏中定义宏
您不能创建一个本身包含以下内容的宏 :
#define
或其替换文本中的任何其他预处理器指令。如果调用外部宏,则扩展不会将内部
#define
解释为预处理器指令,因此它几乎总是以错误结束,在上下文中#
必须是字符串化运算符,并且其后面的单词“define”必须是外部宏的参数名称才有机会工作。生成:
C99 中的
_Pragma
是“宏扩展不能包含预处理器指令”的部分异常,但它 (_Pragma
) 不以# 开头
。What exactly is your desired output? You need to explain what you think you might get as output from the C preprocessor.
You have scope problems and an attempt to define a macro inside the replacement text of another macro.
Scope
The macro
make_def()
invokes an undefined function 'func_call'. Thecreatestuff()
function uses an undefined variablemydata
. And functiondostuff()
seems to call an undefined functionsomefunc_call()
with an enum that might, perhaps, have been defined inside a separate function.If an enumeration is defined inside one function, that enumeration is not available to code outside that function, and specifically is not available to either called functions or calling functions. That alone limits the utility of what you seem to be attempting to do. (Yes, the enumeration values might be implicitly converted to
int
or some similar type, but it is not really the enumeration type that is being used.)Defining macros in macros
You cannot create a macro that itself contains
#define
or any other preprocessor directive in its replacement text.If the outer macro is invoked, the expansion does not interpret the inner
#define
as being a preprocessor directive, so it almost always ends up as an error, In context the#
must be a stringize operator, and the word 'define' after it would have to be the name of an argument to the outer macro to have a chance of working.Generates:
The
_Pragma
in C99 is a partial exception to the 'a macro expansion cannot contain a preprocessor directive', but it (_Pragma
) does not start with#
.您的宏不正确,因为您不能使用一个宏来创建另一个宏,不幸的是,因为令牌 # 在扩展列表中具有特殊含义:它可以引用宏参数,也可以扩展另一个宏。一种简单(尽管设计不佳)的方法就是使用旧的 c 风格 #define MY_ENUM_NAME value ,因为 c 宏不尊重范围,但这不是一个好的设计。另一种可能性是传入字符串参数并对其进行哈希处理,但这一切都取决于您想要执行的操作。
Your macro is incorrect, since you cannot use a macro to create another macro, unfortunately, as the toke # has special meaning in the expansion-list: it can either quote a macro argument, or expand another macro. One easy (albeit poorly designed) way you could do this is just to use old c-style
#define MY_ENUM_NAME value
as c macro do not respect scope, but this would not be good design. Another possibility is to pass in string arguments and hash on them, but all depends on what you want to do.